#!/usr/bin/env python
# encoding: utf-8

import time
import os
import wx
from pyo import *
from pyolib._wxwidgets import VuMeter, ControlSlider
from audio import *
from mixeur import *

# Variables globales pour incrementation dans interpolation
i = 0
i1 = 0

# Variables globales pour communication OSC
hostipad = "169.254.220.192"
hostordi = "169.254.42.178"

# Classe qui recoit la data envoyee par le IPAD
class oscRec():
    def __init__(self):
        # Lien avec classes de matrice.py
        self.reverbdata = ReverbF
        self.bitdata = BitReducerF
        self.loopingdata = LoopingF
        self.mixeurdata = MixeurF
        self.main = mainFrame
        # Lien avec classes de mixeur.py
        self.audio = audio
        self.process = reverb
        self.process2 = bitreduce
        self.mixeur = mixeur

        self.oscIpadReceive = OscDataReceive(8100, [
        '/pitch', '/start', '/gainmaster', '/reverbframe', '/bitreduceframe','/loopeurframe', '/mixeurframe', '/duration', '/xfade',
         '/sizemini', '/sizemaxi', '/beatsize', '/dampmini', '/dampaxi', '/deatdamp', '/timepreset', '/timeinterp',
         '/morphrev12', '/morphrev23', '/coslinrev12', '/coslinrev23', '/seqpresetrev', '/seqpresetrevrandom', '/seqpresetrevstop',
         '/presetrev1s', '/presetrev1r', '/presetrev2s', '/presetrev2r', '/presetrev3s', '/presetrev3r',
         '/ramdirect', '/rambitreduce', '/ramreverb', '/rambrreverb', '/ramreverbbr',
         '/indirect', '/inbitreduce', '/inreverb', '/inbrreverb', '/inreverbbr',
         '/loopdirect', '/loopbitreduce', '/loopreverb', '/loopbrreverb', '/loopreverbbr',
         '/looppitch', '/looppitchmetro', '/loopstart', '/loopstartmetro', '/loopend', '/loopendmetro',
         '/looprec', '/loopoverdub', '/loopmute', '/loopmuteafplay', '/loopplay', '/looperase', '/loopreverse', '/looprandompitch', '/looprandomend', '/looprandomstart',
         '/bitminim', '/bitmaxim', '/beatbitmetro', '/scaleminim', '/scalemaxim', '/beatscalemetro', '/timepresetbit', '/timeinterpbit',
         '/morphbit12', '/morphbit23', '/coslinbit12', '/coslinbit23',
         '/presetbit1s', '/presetbit1r', '/presetbit2s', '/presetbit2r', '/presetbit3s', '/presetbit3r', '/seqpresetbit', '/seqpresetbitrandom', '/seqpresetbitstop'
         ], self.oscChange)

    def oscChange(self, address, *args):
#### Son Ram ####
        if address == '/pitch':
            x = (args[0])
            self.audio.input.pitch = x
            self.main.changepitch.SetValue(x)
        if address == '/start':
            x = (args[0])
            self.audio.input.start = x
            self.main.changestart.SetValue(x)
        if address == '/gainmaster':
            x = (args[0])
            s.setAmp(x)
            self.main.volumemain.SetValue(x)
        if address == '/duration':
            x = (args[0])
            self.audio.input.dur = x
            self.main.changedur.SetValue(x)
        if address == '/xfade':
            x = (args[0])
            self.audio.input.xfade = x
            self.main.changefade.SetValue(x)
        if address == '/reverbframe':
            if (args[0]) == 1:
                self.main.revframe.SetValue(True)
                ReverbF.Show()
            else:
                self.main.revframe.SetValue(False)
                ReverbF.Hide()
        if address == '/bitreduceframe':
            if (args[0]) == 1:
                self.main.bitframe.SetValue(True)
                BitReducerF.Show()
            else:
                BitReducerF.Hide()
                self.main.bitframe.SetValue(False)
        if address == '/loopeurframe':
            if (args[0]) == 1:
                self.main.loopframe.SetValue(True)
                LoopingF.Show()
            else:
                LoopingF.Hide()
                self.main.loopframe.SetValue(False)
        if address == '/mixeurframe':
            if (args[0]) == 1:
                self.main.mixeurf.SetValue(True)
                MixeurF.Show()
            else:
                self.main.mixeurf.SetValue(False)
                MixeurF.Hide()
#### Reverb ####
## Slider ##
        if address == '/sizemini':
            x = (args[0])
            x1 = int(round(x))
            self.process.valeurminimalesize = x1
            self.process.updateSize()
            self.reverbdata.sizemini.SetValue(x1)
        if address == '/sizemaxi':
            x = (args[0])
            x1 = int(round(x))
            self.process.valeurmaximalesize = x1
            self.process.updateSize()
            self.reverbdata.sizemaxi.SetValue(x1)
        if address == '/beatsize':
            x = (args[0])
            self.process.updateBeatSize(x)
            self.reverbdata.beatsize.SetValue(x)
        if address == '/dampmini':
            x = (args[0])
            x1 = int(round(x))
            self.process.valeurminimaledamp = x1
            self.process.updateDamp()
            self.reverbdata.dampminimum.SetValue(x1)
        if address == '/dampmaxi':
            x = (args[0])
            x1 = int(round(x))
            self.process.valeurmaximaledamp = x1
            self.process.updateDamp()
            self.reverbdata.dampmaximum.SetValue(x1)
        if address == '/beatdamp':
            x = (args[0])
            self.process.updateDampTime(x)
            self.reverbdata.beatdamp.SetValue(x)
        if address == '/timepreset':
            x = (args[0])
            self.reverbdata.metro.time = x
            self.reverbdata.timetrigreverb.SetValue(x)
        if address == '/timeinterp':
            x = (args[0])
            self.interreverbtime = x/128
            self.reverbdata.interpdamp1to2.setTime(self.interreverbtime)
            self.reverbdata.interpdamp2to3.setTime(self.interreverbtime)
            self.reverbdata.timeinterreverb.SetValue(x)
## Button ##
        if address == '/morphrev12':
            if (args[0]) == 1:
                self.reverbdata.interpolatePresetReverb1to2(self)
        if address == '/morphrev23':
            if (args[0]) == 1:
                self.reverbdata.interpolatePresetReverb2to3(self)
        if address == '/coslinrev12':
            if (args[0]) == 1:
                self.reverbdata.linorcosrev1to2.SetValue(True)
                self.reverbdata.reverb1to2CosorLin(self)
            elif (args[0]) == 0:
                self.reverbdata.linorcosrev1to2.SetValue(False)
                self.reverbdata.reverb1to2CosorLin(self)
        if address == '/coslinrev23':
            if (args[0]) == 1:
                self.reverbdata.linorcosrev2to3.SetValue(True)
                self.reverbdata.reverb2to3CosorLin(self)
            elif (args[0]) == 0:
                self.reverbdata.linorcosrev2to3.SetValue(False)
                self.reverbdata.reverb2to3CosorLin(self)

        if address == '/presetrev1s':
            if (args[0]) == 1:
                self.reverbdata.getpreset1Reverb(self)
        if address == '/presetrev1r':
            if (args[0]) == 1:
                self.reverbdata.setpreset1Reverb(self)
        if address == '/presetrev2s':
            if (args[0]) == 1:
                self.reverbdata.getpreset2Reverb(self)
        if address == '/presetrev2r':
            if (args[0]) == 1:
                self.reverbdata.setpreset2Reverb(self)
        if address == '/presetrev3s':
            if (args[0]) == 1:
                self.reverbdata.getpreset3Reverb(self)
        if address == '/presetrev3r':
            if (args[0]) == 1:
                self.reverbdata.setpreset3Reverb(self)
        if address == '/seqpresetrev':
            if (args[0]) == 1:
                self.reverbdata.startLoopingPreset(self)
        if address == '/seqpresetrevrandom':
            if (args[0]) == 1:
                self.reverbdata.startLoopingPresetRandom(self)
        if address == '/seqpresetrevstop':
            if (args[0]) == 1:
                self.reverbdata.stopLoopingPreset(self)

#### Mixeur ####
## Slider ##
        if address =='/ramdirect':
            x = (args[0])
            self.ramdirectout = x
            self.mixeur.mm.setAmp(0, 0, self.ramdirectout)
            self.mixeurdata.volumeramdirect.SetValue(x)
        if address =='/ramreverb':
            x = (args[0])
            self.volumeramdelai = x
            self.mixeur.mm.setAmp(0, 2, self.volumeramdelai)
            self.mixeurdata.volumeramdelais.SetValue(x)
        if address =='/rambitreduce':
            x = (args[0])
            self.volumerambit = x
            self.mixeur.mm.setAmp(0, 1, self.volumerambit)
            self.mixeurdata.volumerambitreduce.SetValue(x)
        if address =='/rambrreverb':
            x = (args[0])
            self.volumebrdelai = x
            self.volumerambit = x
            self.mixeur.mm.setAmp(0, 1, self.volumerambit)
            self.mixeur.mm.setAmp(2, 2, self.volumebrdelai)
            self.mixeurdata.volumebrdelais.SetValue(x)
        if address =='/ramreverbbr':
            x = (args[0])
            self.volumereverbbr = x
            self.volumeramdelai = x
            self.mixeur.mm.setAmp(0, 2, self.volumeramdelai)
            self.mixeur.mm.setAmp(3, 1, self.volumereverbbr)
            self.mixeurdata.volumereverbbre.SetValue(x)
        if address =='/indirect':
            x = (args[0])
            self.mixeur.mm.setAmp(1, 0, x)
            self.mixeurdata.volumeentree1direct.SetValue(x)
        if address =='/inbitreduce':
            x = (args[0])
            self.mixeur.mm.setAmp(1, 1, x)
            self.mixeurdata.volumeentree1bitreduces.SetValue(x)
        if address =='/inreverb':
            x = (args[0])
            self.volumeentree1delai = x
            self.mixeur.mm.setAmp(1, 2, self.volumeentree1delai)
            self.mixeurdata.volumeentree1delais.SetValue(x)
        if address =='/inbrreverb':
            x = (args[0])
            self.mixeur.mm.setAmp(1, 1, x)
            self.mixeur.mm.setAmp(2, 2, x)
            self.mixeurdata.volumebrdelaiins.SetValue(x)
        if address =='/inreverbbr':
            x = (args[0])
            self.mixeur.mm.setAmp(1, 2, x)
            self.mixeur.mm.setAmp(3, 1, x)
            self.mixeurdata.volumereverbbrins.SetValue(x)

        if address =='/loopdirect':
            x = (args[0])
            self.mixeur.mm.setAmp(4, 0, x)
            self.mixeurdata.volumeloopdirects.SetValue(x)
        if address =='/loopbitreduce':
            x = (args[0])
            self.mixeur.mm.setAmp(4, 1, x)
            self.mixeurdata.volumeloopbitreduces.SetValue(x)
        if address =='/loopreverb':
            x = (args[0])
            self.volumeloopreverb = x
            self.mixeur.mm.setAmp(4, 2, x)
            self.mixeurdata.volumeloopreverbs.SetValue(x)
        if address =='/loopbrreverb':
            x = (args[0])
            self.mixeur.mm.setAmp(4, 2, x)
            self.mixeur.mm.setAmp(2, 2, x)
            self.mixeurdata.volumeloopbrinreverbs.SetValue(x)
        if address =='/loopreverbbr':
            x = (args[0])
            self.mixeur.mm.setAmp(4, 1, x)
            self.mixeur.mm.setAmp(2, 2, x)
            self.mixeurdata.volumelooppreverbinbr.SetValue(x)
#### Loopeur ####
## Slider ##
        if address == '/looppitch':
            x = (args[0])
            self.audio.looprec.pitch = x
            self.loopingdata.changelooppitch.SetValue(x)
        if address == '/looppitchmetro':
            x = (args[0])
            self.loopingdata.metro.time = x
            self.loopingdata.changemetropitch.SetValue(x)
        if address == '/loopstart':
            x = (args[0])
            self.audio.looprec.start = x
            self.loopingdata.changeloopstart.SetValue(x)
        if address == '/loopstartmetro':
            x = (args[0])
            self.loopingdata.metro3.time = x
            self.loopingdata.changemetrostart.SetValue(x)
        if address == '/loopend':
            x = (args[0])
            self.audio.looprec.dur = x
            self.loopingdata.changeloopdur.SetValue(x)
        if address == '/loopendmetro':
            x = (args[0])
            self.loopingdata.metro3.time = x
            self.loopingdata.changemetrodur.SetValue(x)
#### Loopeur ####
## Button ##
        if address == '/looprec':
            if (args[0]) == 1:
                self.loopingdata.recordloop.SetValue(True)
                self.loopingdata.recordLoop(self)
            elif (args[0]) == 0:
                self.loopingdata.recordloop.SetValue(False)
                self.loopingdata.recordLoop(self)

        if address == '/loopoverdub':
            if (args[0]) == 1:
                self.loopingdata.overdubLoop1(self)
        if address == '/loopmute':
            if (args[0]) == 1:
                self.loopingdata.killLoop1(self)
        if address == '/loopmuteafplay':
            if (args[0]) == 1:
                self.loopingdata.killafterplayLoop1(self)
        if address == '/loopplay':
            if (args[0]) == 1:
                self.loopingdata.playLoop1(self)
        if address == '/looperase':
            if (args[0]) == 1:
                self.loopingdata.eraseLoop1(self)
        if address =='/loopreverse':
            if (args[0]) == 1:
                self.loopingdata.reverseloop.SetValue(True)
                self.loopingdata.reverseLoop(self)
            if (args[0]) == 0:
                self.loopingdata.reverseloop.SetValue(False)
                self.loopingdata.reverseLoop(self)
        if address =='/looprandompitch':
            if (args[0]) == 1:
                self.loopingdata.randompitch.SetValue(True)
                self.loopingdata.pitchRandom(self)
            if (args[0]) == 0:
                self.loopingdata.randompitch.SetValue(False)
                self.loopingdata.pitchRandom(self)
        if address =='/looprandomstart':
            if (args[0]) == 1:
                self.loopingdata.randomstart.SetValue(True)
                self.loopingdata.startRandom(self)
            if (args[0]) == 0:
                self.loopingdata.randomstart.SetValue(False)
                self.loopingdata.startRandom(self)
        if address =='/looprandomend':
            if (args[0]) == 1:
                self.loopingdata.randomdur.SetValue(True)
                self.loopingdata.durRandom(self)
            if (args[0]) == 0:
                self.loopingdata.randomdur.SetValue(False)
                self.loopingdata.durRandom(self)
#### Bit Reducer ####
## Slider ##
        if address == '/bitminim':
            x = (args[0])
            x1 = int(round(x))
            self.process2.valeurminimale = x1
            self.process2.updateSequence()
            self.bitdata.bitmini.SetValue(x1)
        if address == '/bitmaxim':
            x = (args[0])
            x1 = int(round(x))
            self.process2.valeurmaximale = x1
            self.process2.updateSequence()
            self.bitdata.bitmaxi.SetValue(x1)

        if address == '/beatbitmetro':
            x = (args[0])
            self.process2.updateBeatBit(x)
            self.bitdata.beatbit.SetValue(x)
        if address == '/scaleminim':
            x = (args[0])
            x1 = int(round(x))
            self.process2.valeurminimalescale = x1
            self.process2.updateScale()
            self.bitdata.scaleminimum.SetValue(x1)
        if address == '/scalemaxim':
            x = (args[0])
            x1 = int(round(x))
            self.process2.valeurmaximalescale = x1
            self.process2.updateScale()
            self.bitdata.scalemaximum.SetValue(x1)
        if address == '/beatscalemetro':
            x = (args[0])
            self.process2.updateBeatScale(x)
            self.bitdata.beatscale.SetValue(x)
        if address == '/timepresetbit':
            x = (args[0])
            self.bitdata.metro.time = x
            self.bitdata.timetrig.SetValue(x)
        if address == '/timeinterpbit':
            x = (args[0])
            self.interbittime = x/128
            self.bitdata.interpbit1to2.setTime(self.interbittime)
            self.bitdata.interpbit1to2.setTime(self.interbittime)
            self.bitdata.timeinterbit.SetValue(x)

## Button ##
        if address == '/morphbit12':
            if (args[0]) == 1:
                self.bitdata.interpolatePresetBit1to2(self)
        if address == '/morphbit23':
            if (args[0]) == 1:
                self.bitdata.interpolatePresetBit2to3(self)
        if address == '/coslinbit12':
            if (args[0]) == 1:
                self.bitdata.linorcosbit1to2.SetValue(True)
                self.bitdata.bit1to2CosorLin(self)
            elif (args[0]) == 0:
                self.bitdata.linorcosbit1to2.SetValue(False)
                self.bitdata.bit1to2CosorLin(self)
        if address == '/coslinbit23':
            if (args[0]) == 1:
                self.bitdata.linorcosbit2to3.SetValue(True)
                self.bitdata.bit2to3CosorLin(self)
            elif (args[0]) == 0:
                self.bitdata.linorcosbit2to3.SetValue(False)
                self.bitdata.bit2to3CosorLin(self)
        if address == '/presetbit1s':
            if (args[0]) == 1:
                self.bitdata.getpreset1BitReducer(self)
        if address == '/presetbit1r':
            if (args[0]) == 1:
                self.bitdata.setpreset1BitReducer(self)
        if address == '/presetbit2s':
            if (args[0]) == 1:
                self.bitdata.getpreset2BitReducer(self)
        if address == '/presetbit2r':
            if (args[0]) == 1:
                self.bitdata.setpreset2BitReducer(self)
        if address == '/presetbit3s':
            if (args[0]) == 1:
                self.bitdata.getpreset3BitReducer(self)
        if address == '/presetbit3r':
            if (args[0]) == 1:
                self.bitdata.setpreset3BitReducer(self)

        if address == '/seqpresetbit':
            if (args[0]) == 1:
                self.bitdata.startLoopingPreset(self)
        if address == '/seqpresetbitrandom':
            if (args[0]) == 1:
                self.bitdata.startLoopingPresetRandom(self)
        if address == '/seqpresetbitstop':
            if (args[0]) == 1:
                self.bitdata.stopLoopingPreset(self)

class MyFrame(wx.Frame):
    def __init__(self, parent=None,id=1, title="Matrice", pos=(0,50), size=(225,800), switcher=None):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)
        self.SetMinSize((225, 700))

        # Ordi vers Lemur (Port Incoming, Host = Local IP Adress (celui du IPAD - Local IP Address))
        self.oscIpad = OscDataSend(types='f', port=8000, address=['/pitch', '/start', '/gainmaster', '/reverbframe', '/bitreduceframe',
        '/loopeurframe', '/mixeurframe', '/duration', '/xfade'], host=hostipad)
        # Lemur vers Ordi (Port Outgoing, Host = IP de l'ordi (voir pref Reseaux et changer dans TouchOSC)
        self.oscIpad2 = OscDataSend(types='f', port=8100, address=['/pitch', '/start', '/gainmaster', '/reverbframe', '/bitreduceframe',
        '/loopeurframe', '/mixeurframe', '/duration', '/xfade'], host=hostordi)

        # Lien
        self.switcher = switcher
        self.audio = audio

        # Event sur la fermeture du main frame
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        # Panneau principal
        self.panel = wx.Panel(self)

        # Gestion dynamique de l'espace
        self.box = wx.BoxSizer(wx.VERTICAL)

        # On assigne la boite au panneau principal
        self.panel.SetSizer(self.box)

        self.audioServer = AudioServer()

        # Creation du menu
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        audioMenu = wx.Menu()
        windowMenu = wx.Menu()

        audioMenu.Append(30, "Start Server\tCtrl+R", kind=wx.ITEM_CHECK)
        audioMenu.Append(31, "Record Audio\tCtrl+E", kind=wx.ITEM_CHECK)
        audioMenu.Append(32, "Load Sound\tCtrl+L", kind=wx.ITEM_NORMAL)
        audioMenu.Append(33, "Close\tCtrl+Q", kind=wx.ITEM_NORMAL)

        audioMenu.AppendSeparator()

        self.names, default = self.audioServer.getAudioDriverNames()
        for i, name in enumerate(self.names):
            audioMenu.Append(i+9000, name, kind=wx.ITEM_RADIO)
            if name == default:
                audioMenu.Check(i+9000, True)
            self.Bind(wx.EVT_MENU, self.changeAudioDriver, id=i+9000)

        audioMenu.AppendSeparator()

        self.names1, default = self.audioServer.getAudioDriverNames1()
        for i, name1 in enumerate(self.names1):
            audioMenu.Append(i+10000, name1, kind=wx.ITEM_RADIO)
            if name1 == default:
                audioMenu.Check(i+10000, True)
            self.Bind(wx.EVT_MENU, self.changeAudioDriver1, id=i+10000)

        windowMenu.Append(40, "Reverb\tCTRL+1", kind=wx.ITEM_CHECK)
        self.Bind(wx.EVT_MENU, self.openReverb, id=40)
        windowMenu.Append(41, "Bit Reducer\tCTRL+2", kind=wx.ITEM_CHECK)
        self.Bind(wx.EVT_MENU, self.openPageBit, id=41)
        windowMenu.Append(42, "Looper\tCTRL+3", kind=wx.ITEM_CHECK)
        self.Bind(wx.EVT_MENU, self.openLooper, id=42)
        windowMenu.Append(43, "Mixer\tCTRL+4", kind=wx.ITEM_CHECK)
        self.Bind(wx.EVT_MENU, self.openPageMixeur, id=43)

        self.Bind(wx.EVT_MENU, self.handleAudio, id=30)
        self.Bind(wx.EVT_MENU, self.recordMaster, id=31)
        self.Bind(wx.EVT_MENU, self.loadSnd, id=32)
        self.Bind(wx.EVT_MENU, self.OnClose, id=33)

        menubar.Append(audioMenu, "Audio")
        menubar.Append(windowMenu, "Window")
        self.SetMenuBar(menubar)

        # Ajout d'une boite dans une boite
        self.buttonBox = wx.BoxSizer(wx.VERTICAL)
        self.sliderBox = wx.BoxSizer(wx.VERTICAL)

        # Meter amplitude son RAM
        self.meter = VuMeter(self.panel, numSliders=2)
        self.box.Add(item = self.meter, flag = wx.ALL, border = 10, proportion = 0)

        # Assignation du meter au serveur
        s._server.setAmpCallable(self.meter)

        # Bouton pour ouvrir un dialogue standard et selectionner un nouveau son
        self.chooseButton = wx.Button(self.panel, id=-1, label="Load Sound")
        self.chooseButton.Bind(wx.EVT_BUTTON, self.loadSnd)
        self.sliderBox.Add(item = self.chooseButton, flag = wx.EXPAND|wx.BOTTOM, border = 5, proportion = 0)

        # Barre defilante input
        fxs = ['Input 1', 'Input 2', 'Input 3', 'Input 4']
        self.popup1 = wx.Choice(self.panel, id=-1, choices=fxs)
        self.buttonBox.Add(item = self.popup1, flag = wx.EXPAND|wx.ALL, border = 10, proportion = 0)
        self.popup1.Bind(wx.EVT_CHOICE, self.changeInputMaster)

        # Slider Volume Main
        self.volumemainText = wx.StaticText(self.panel, id=-1, label=" Gain Systeme / 1")
        self.volumemain = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.5, log=False, outFunction=self.changeVolumeMain, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.volumemainText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.volumemain, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Pitch Loop
        self.changepitchText = wx.StaticText(self.panel, id=-1, label=" Pitch Loop / 4", pos=(20,202))
        self.changepitch = ControlSlider(self.panel, minvalue=0.1, maxvalue=4, init=1, log=False, outFunction=self.changePitch, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changepitchText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changepitch, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Start Loop
        self.changestartText = wx.StaticText(self.panel, id=-1, label=" Start Loop (s)")
        self.changestart = ControlSlider(self.panel, minvalue=0, maxvalue=self.audio.lentable, init=0, log=False, outFunction=self.changeStart, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changestartText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changestart, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Dur Loop
        self.changedurText = wx.StaticText(self.panel, id=-1, label=" Duration Loop (s)")
        self.changedur = ControlSlider(self.panel, minvalue=0, maxvalue=self.audio.lentable, init=self.audio.lentable, log=False, outFunction=self.changeDur, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add (item = self.changedurText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changedur, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Xfade Loop
        self.changefadeText = wx.StaticText(self.panel, id=-1, label=" Xfade Loop (s)")
        self.changefade = ControlSlider(self.panel, minvalue=0.01, maxvalue=self.audio.lentable, init= 0.5, log=False, outFunction=self.changeFade, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changefadeText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changefade, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Change valeur slideur Start Time et Dur Time et XFade du Looper
        self.audio.setSliders(self.changestart, self.changedur, self.changefade)

        # Bouton Reverb
        self.revframe = wx.ToggleButton(self.panel, id=-1, label="Reverb")
        self.revframe.Bind(wx.EVT_TOGGLEBUTTON, self.openReverb)
        self.buttonBox.Add(item = self.revframe, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Bit Reducer
        self.bitframe = wx.ToggleButton(self.panel, id=-1, label="Reducer")
        self.bitframe.Bind(wx.EVT_TOGGLEBUTTON, self.openPageBit)
        self.buttonBox.Add(item = self.bitframe, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Loop
        self.loopframe = wx.ToggleButton(self.panel, id=-1, label="Loop")
        self.loopframe.Bind(wx.EVT_TOGGLEBUTTON, self.openLooper)
        self.buttonBox.Add(item = self.loopframe, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Mixeur
        self.mixeurf = wx.ToggleButton(self.panel, id=-1, label="Mixer")
        self.mixeurf.Bind(wx.EVT_TOGGLEBUTTON, self.openPageMixeur)
        self.buttonBox.Add(item = self.mixeurf, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        self.box.Add(item = self.sliderBox, proportion = 0, flag = wx.EXPAND|wx.BOTTOM, border = 20)
        self.box.Add(item = self.buttonBox, proportion = 0, flag = wx.EXPAND|wx.ALL, border = 20)

        # Affiche la fenetre
        self.Show()

    # Change In / Out
    def changeAudioDriver(self, evt):
        name = self.names[evt.GetId()-9000]
        self.audioServer.changeAudioDriver(name)

    def changeAudioDriver1(self, evt):

        name1 = self.names1[evt.GetId()-10000]
        self.audioServer.changeAudioDriver1(name1)

    def onStartStop(self, evt):
        if evt.GetInt() == 1:
            self.audioServer.start()
        else:
            self.audioServer.stop()

#   # Ferme de facon propre le serveur
    def OnClose(self, evt):
        print "Fin..."
        if s.getIsStarted():
            s.stop()
            time.sleep(.25)
        s.shutdown()
        time.sleep(.25)
        self.Destroy()
        time.sleep(.10)
        BitReducerF.Destroy()
        time.sleep(.10)
        MixeurF.Destroy()
        time.sleep(.10)
        ReverbF.Destroy()
        time.sleep(.10)
        LoopingF.Destroy()

    # Part le serveur (bouton GO)
    def handleAudio(self, evt):
        if evt.GetInt() == 1:
            s.start()
        else:
            s.stop()

    # Choix Input
    def changeInputMaster(self, evt):
        if evt.GetInt() == 0:
            print "Input 1"
            self.audio.input1.voice = 0.
        elif evt.GetInt() == 1:
            self.audio.input1.voice = 1.
            print "Input 2"
        elif evt.GetInt() == 2:
            self.audio.input1.voice = 2.
            print "Input 3"
        elif evt.GetInt() == 3:
            self.audio.input1.voice = 3.
            print "Input 4"

    # Part l'enregistrement (bouton RECORD)
    def recordMaster(self, evt):
        if evt.GetInt() == 1:
            s.recstart(os.path.abspath("record/BouncePyo.wav"))
        else:
            s.recstop()

    # Ouverture du Bit Reducer
    def openPageBit(self, evt):
        if evt.GetInt() == 1:
            BitReducerF.Show()
            self.oscIpad.send([1], '/bitreduceframe')
        else:
            BitReducerF.Hide()
            self.oscIpad.send([0], '/bitreduceframe')

    # Ouverture du Reverb
    def openReverb(self, evt):
        if evt.GetInt() == 1:
            ReverbF.Show()
            self.oscIpad.send([1], '/reverbframe')
        else:
            ReverbF.Hide()
            self.oscIpad.send([0], '/reverbframe')

    # Ouverture du Mixeur
    def openPageMixeur(self, evt):
        if evt.GetInt() == 1:
            MixeurF.Show()
            self.oscIpad.send([1], '/mixeurframe')
        else:
            MixeurF.Hide()
            self.oscIpad.send([0], '/mixeurframe')

    # Ouverture du Looper
    def openLooper(self, evt):
        if evt.GetInt() == 1:
            LoopingF.Show()
            self.oscIpad.send([1], '/loopeurframe')
        else:
            LoopingF.Hide()
            self.oscIpad.send([0], '/loopeurframe')

    # Volume Master
    def changeVolumeMain(self, value):
        x = value
        s.setAmp(x)
        self.oscIpad.send([x], '/gainmaster')

    def setSound(self, evt):
        x = self.pit.GetValue() * 0.001
        self.audio.table.setSound = (evt.GetString())
        self.audio.input.freq = self.audio.table.getRate() * x

    # Pitch Loop
    def changePitch(self, value):
        x = value
        self.audio.input.pitch = x
        self.oscIpad.send([x], '/pitch')

    # Start Loop
    def changeStart(self, value):
        x = value
        self.audio.input.start = x
        self.oscIpad.send([x], '/start')
    # Duration Loop
    def changeDur(self, value):
        x = value
        self.audio.input.dur = x
        self.oscIpad.send([x], '/duration')
    # Xfade Loop
    def changeFade(self, value):
        x = value
        self.audio.input.xfade = x
        self.oscIpad.send([x], '/xfade')

    # Filtrage des fichiers disponibles
    def loadSnd(self, evt):
        wildcard = "All files|*.*|" \
                   "AIFF file|*.aif;*.aiff;*.aifc;*.AIF;*.AIFF;*.Aif;*.Aiff|" \
                   "Wave file|*.wav;*.wave;*.WAV;*.WAVE;*.Wav;*.Wave"
        dlg = wx.FileDialog(self, message="Choose a new soundfile...", wildcard=wildcard, style=wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            if path != "":
                self.switcher.changeTable(path)
        dlg.Destroy()

class ReverbFrame(wx.Frame):
    def __init__(self, parent, title, pos, size, process):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)
        self.panel = wx.Panel(self)
        self.SetMinSize((350,800))
        self.panel.SetBackgroundColour("#DDDDDD")
        self.process = process
        self.box = wx.BoxSizer(wx.VERTICAL)

        # Ordi vers Lemur (Port Incoming, Host = Local IP Adress (celui du IPAD - Local IP Address))
        self.oscIpad = OscDataSend(types='f', port=8000, address=['/sizemini', '/sizemaxi', '/beatsize', '/dampmini', '/dampmaxi', '/beatdamp', '/timepreset',
         '/timeinterp', '/morphrev12', '/morphrev23', '/coslinrev12', '/coslinrev23', '/presetrev1s', '/presetrev1r', '/presetrev2s', '/presetrev2r',
         '/presetrev3s', '/presetrev3r', '/seqpresetrev', '/seqpresetrevrandom', '/seqpresetrevstop'], host=hostipad)
        # Lemur vers Ordi (Port Outgoing, Host = IP de l'ordi (voir pref Reseaux et changer dans TouchOSC)
        self.oscIpad2 = OscDataSend(types='f', port=8100, address=['/sizemini', '/sizemaxi', '/beatsize', '/dampmini', '/dampaxi', '/beatdamp', '/timepreset',
        '/timeinterp','/morphrev12', '/morphrev23', '/coslinrev12', '/coslinrev23', '/presetrev1s', '/presetrev1r', '/presetrev2s', '/presetrev2r',
        '/presetrev3s', '/presetrev3r', '/seqpresetrev', '/seqpresetrevrandom', '/seqpresetrevstop'], host=hostordi)

        self.sliderBox = wx.BoxSizer(wx.VERTICAL)
        self.interpolationBox = wx.BoxSizer(wx.HORIZONTAL)
        self.cosorlinBox = wx.BoxSizer(wx.HORIZONTAL)
        self.preset1Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset2Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset3Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset4Box = wx.BoxSizer(wx.HORIZONTAL)

        self.panel.SetSizer(self.box)

        self.Bind(wx.EVT_CLOSE, self.reverbClose)

        # Trig de preset
        self.presetNum = 0
        self.metro = Metro(time=2)
        self.trigger = TrigFunc(self.metro, function=self.trigPreset)
        self.interpdamp1to2 = Pattern(self.presetReverb1to2, time=0.015625)
        self.interpdamp2to3 = Pattern(self.presetReverb2to3, time=0.015625)

        # Slider size valeur minimale
        self.sizeminiText = wx.StaticText(self.panel, id=-1, label="Size Minimum %")
        self.sizemini = ControlSlider(self.panel, minvalue=0, maxvalue=100, init=25, log=False, outFunction=self.sizeMinimum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.sizeminiText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.sizemini, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider size valeur maximale
        self.sizemaxiText = wx.StaticText(self.panel, id=-1, label="Size Maximum %")
        self.sizemaxi = ControlSlider(self.panel, minvalue=0, maxvalue=100, init=85, log=False, outFunction=self.sizeMaximum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.sizemaxiText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.sizemaxi, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Beat size
        self.beatsizeText = wx.StaticText(self.panel, id=-1, label="Beat Size (s) / 5 ")
        self.beatsize = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.changeBeatSize, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.beatsizeText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.beatsize, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Damp valeur minimale
        self.dampminimumText = wx.StaticText(self.panel, id=-1, label="Damp Minimum %")
        self.dampminimum = ControlSlider(self.panel, minvalue=0, maxvalue=100, init=10, log=False, outFunction=self.dampMinimum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.dampminimumText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.dampminimum, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Damp valeur maximale
        self.dampmaximumText = wx.StaticText(self.panel, id=-1, label="Damp Maximum %")
        self.dampmaximum = ControlSlider(self.panel, minvalue=0, maxvalue=100, init=90, log=False, outFunction=self.dampMaximum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.dampmaximumText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.dampmaximum, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Beat Damp
        self.beatdampText = wx.StaticText(self.panel, id=-1, label="Beat Damp (s) / 5 ")
        self.beatdamp = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.changeDampTime, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.beatdampText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.beatdamp, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Temps Trig
        self.timetrigreverbText = wx.StaticText(self.panel, id=-1, label="Temps Preset (s) / 5 ")
        self.timetrigreverb = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.timeTrigReverb, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.timetrigreverbText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.timetrigreverb, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Temps Interpolation
        self.timeinterreverbText = wx.StaticText(self.panel, id=-1, label="Temps Interpolation (s) / 10 ")
        self.timeinterreverb = ControlSlider(self.panel, minvalue=1, maxvalue=10, init=2, log=False, outFunction=self.timeInterReverb, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.timeinterreverbText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.timeinterreverb, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Preset 1 Reverb
        self.preset1reverbsaveText = wx.StaticText(self.panel, id=-1, label="Preset 1")
        self.preset1reverbsaveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset1reverbsaveButton.Bind(wx.EVT_BUTTON, self.getpreset1Reverb)
        self.preset1Box.Add(item = self.preset1reverbsaveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset1Box.Add(item = self.preset1reverbsaveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 1 Reverb
        self.preset1reverbrecallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset1reverbrecallButton.Bind(wx.EVT_BUTTON, self.setpreset1Reverb)
        self.preset1Box.Add(item = self.preset1reverbrecallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 2 Reverb
        self.preset2reverbsaveText = wx.StaticText(self.panel, id=-1, label="Preset 2")
        self.preset2reverbsaveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset2reverbsaveButton.Bind(wx.EVT_BUTTON, self.getpreset2Reverb)
        self.preset2Box.Add(item = self.preset2reverbsaveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset2Box.Add(item = self.preset2reverbsaveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 2 Reverb
        self.preset2reverbrecallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset2reverbrecallButton.Bind(wx.EVT_BUTTON, self.setpreset2Reverb)
        self.preset2Box.Add(item = self.preset2reverbrecallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 3 Reverb
        self.preset3reverbsaveText = wx.StaticText(self.panel, id=-1, label="Preset 3")
        self.preset3reverbsaveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset3reverbsaveButton.Bind(wx.EVT_BUTTON, self.getpreset3Reverb)
        self.preset3Box.Add(item = self.preset3reverbsaveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset3Box.Add(item = self.preset3reverbsaveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 3 Reverb
        self.preset3reverbrecallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset3reverbrecallButton.Bind(wx.EVT_BUTTON, self.setpreset3Reverb)
        self.preset3Box.Add(item = self.preset3reverbrecallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset GO
        self.trigpresetText = wx.StaticText(self.panel, id=-1, label="Seq       ")
        self.trigpresetButton = wx.Button(self.panel, id=-1, label="Linear")
        self.trigpresetButton.Bind(wx.EVT_BUTTON, self.startLoopingPreset)
        self.preset4Box.Add(item = self.trigpresetText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset4Box.Add(item = self.trigpresetButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset Random GO
        self.trigpresetButtonRandom = wx.Button(self.panel, id=-1, label="Random")
        self.trigpresetButtonRandom.Bind(wx.EVT_BUTTON, self.startLoopingPresetRandom)
        self.preset4Box.Add(item = self.trigpresetButtonRandom, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset OFF
        self.trigpresetstopButton = wx.Button(self.panel, id=-1, label="Stop")
        self.trigpresetstopButton.Bind(wx.EVT_BUTTON, self.stopLoopingPreset)
        self.preset4Box.Add(item = self.trigpresetstopButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Interpolate 1 to 2
        self.interpolatereverbText = wx.StaticText(self.panel, id=-1, label="Interp   ")
        self.presetinterpolateButton = wx.Button(self.panel, id=-1, label="Morph 1-2")
        self.presetinterpolateButton.Bind(wx.EVT_BUTTON, self.interpolatePresetReverb1to2)
        self.interpolationBox.Add(item = self.interpolatereverbText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.interpolationBox.Add(item = self.presetinterpolateButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Interpolate 2 to 3
        self.presetinterpolate2Button = wx.Button(self.panel, id=-1, label="Morph 2-3")
        self.presetinterpolate2Button.Bind(wx.EVT_BUTTON, self.interpolatePresetReverb2to3)
        self.interpolationBox.Add(item = self.presetinterpolate2Button, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Lin or Cos 1 to 2
        self.linorcosrev1to2Text = wx.StaticText(self.panel, id=-1, label="Mode   ")
        self.linorcosrev1to2 = wx.ToggleButton(self.panel, id=-1, label="Cos / Lin")
        self.linorcosrev1to2.Bind(wx.EVT_TOGGLEBUTTON, self.reverb1to2CosorLin)
        self.cosorlinBox.Add(item = self.linorcosrev1to2Text, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.cosorlinBox.Add(item = self.linorcosrev1to2, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Lin or Cos 2 to 3
        self.linorcosrev2to3 = wx.ToggleButton(self.panel, id=-1, label="Cos / Lin")
        self.linorcosrev2to3.Bind(wx.EVT_TOGGLEBUTTON, self.reverb2to3CosorLin)
        self.cosorlinBox.Add(item = self.linorcosrev2to3, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        self.box.Add(item = self.sliderBox, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 20)
        self.box.Add(item = self.interpolationBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.cosorlinBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset1Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset2Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset3Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset4Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)

    def reverbClose(self, evt):
        self.Hide()

    def sizeMinimum(self, value):
        x = value
        self.process.valeurminimalesize = int(x)
        self.process.updateSize()
        self.oscIpad.send([x], '/sizemini')

    def sizeMaximum(self, value):
        x = value
        self.process.valeurmaximalesize = int(x)
        self.process.updateSize()
        self.oscIpad.send([x], '/sizemaxi')

    def dampMinimum(self, value):
        x = value
        self.process.valeurminimaledamp = int(x)
        self.process.updateDamp()
        self.oscIpad.send([x], '/dampmini')

    def dampMaximum(self, value):
        x = value
        self.process.valeurmaximaledamp = int(x)
        self.process.updateDamp()
        self.oscIpad.send([x], '/dampmaxi')

    def changeBeatSize(self, value):
        x = value
        self.process.updateBeatSize(x)
        self.oscIpad.send([x], '/beatsize')

    def changeDampTime(self, value):
        x = value
        self.process.updateDampTime(x)
        self.oscIpad.send([x], '/beatdamp')

    # Ecriture du preset 1
    def getpreset1Reverb(self, evt=None):
        dic = {"valeurminimalesize": self.process.valeurminimalesize, "valeurmaximalesize": self.process.valeurmaximalesize, "valeurminimaledamp" : self.process.valeurminimaledamp, "valeurmaximaledamp" : self.process.valeurmaximaledamp}
        f = open(os.path.abspath("preset/reverb/ReverbPreset1"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 1
    def setpreset1Reverb(self, evt=None):
        f = open(os.path.abspath("preset/reverb/ReverbPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Size
        self.process.valeurminimalesize = dic["valeurminimalesize"]
        self.sizemini.SetValue(int(dic["valeurminimalesize"]))
        self.process.valeurmaximalesize = dic["valeurmaximalesize"]
        self.sizemaxi.SetValue(int(dic["valeurmaximalesize"]))
        self.process.updateSize()

        # Preset Damp
        self.process.valeurminimaledamp = dic["valeurminimaledamp"]
        self.dampminimum.SetValue(int(dic["valeurminimaledamp"]))
        self.process.valeurmaximaledamp = dic["valeurmaximaledamp"]
        self.dampmaximum.SetValue(int(dic["valeurmaximaledamp"]))
        self.process.updateDamp()

    # Ecriture du preset 2
    def getpreset2Reverb(self, evt=None):
        dic = {"valeurminimalesize": self.process.valeurminimalesize, "valeurmaximalesize": self.process.valeurmaximalesize, "valeurminimaledamp" : self.process.valeurminimaledamp, "valeurmaximaledamp" : self.process.valeurmaximaledamp}
        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 2
    def setpreset2Reverb(self, evt=None):
        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Size
        self.process.valeurminimalesize = dic["valeurminimalesize"]
        self.sizemini.SetValue(int(dic["valeurminimalesize"]))
        self.process.valeurmaximalesize = dic["valeurmaximalesize"]
        self.sizemaxi.SetValue(int(dic["valeurmaximalesize"]))
        self.process.updateSize()

        # Preset Damp
        self.process.valeurminimaledamp = dic["valeurminimaledamp"]
        self.dampminimum.SetValue(int(dic["valeurminimaledamp"]))
        self.process.valeurmaximaledamp = dic["valeurmaximaledamp"]
        self.dampmaximum.SetValue(int(dic["valeurmaximaledamp"]))
        self.process.updateDamp()
# Interpolation de preset
    def interpolatePresetReverb1to2(self, evt):

        f = open(os.path.abspath("preset/reverb/ReverbPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset1 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset1 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset1 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset1 = dic["valeurmaximalesize"]

        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset2 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset2 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset2 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset2 = dic["valeurmaximalesize"]

        # Valeur min damp Preset 1 to 2
        self.acos = CosTable(list=[(0, self.valeurmindamppreset1), (128, self.valeurmindamppreset2)], size=128)

        # Valeur max damp Preset 1 to 2
        self.acos2 = CosTable(list=[(0, self.valeurmaxdamppreset1), (128, self.valeurmaxdamppreset2)], size=128)

        # Valeur min size Preset 1 to 2
        self.acos3 = CosTable(list=[(0, self.valeurminsizepreset1), (128, self.valeurminsizepreset2)], size=128)

        # Valeur max size Preset 1 to 2
        self.acos4 = CosTable(list=[(0, self.valeurmaxsizepreset1), (128, self.valeurmaxsizepreset2)], size=128)

        self.interpdamp1to2.play()

# Interpolation de preset
    def interpolatePresetReverb2to3(self, evt):

        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset2 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset2 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset2 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset2 = dic["valeurmaximalesize"]

        f = open(os.path.abspath("preset/reverb/ReverbPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset3 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset3 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset3 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset3 = dic["valeurmaximalesize"]

        # Valeur min damp Preset 1 to 2
        self.acos = CosTable(list=[(0, self.valeurmindamppreset2), (128, self.valeurmindamppreset3)], size=128)

        # Valeur max damp Preset 1 to 2
        self.acos2 = CosTable(list=[(0, self.valeurmaxdamppreset2), (128, self.valeurmaxdamppreset3)], size=128)

        # Valeur min size Preset 1 to 2
        self.acos3 = CosTable(list=[(0, self.valeurminsizepreset2), (128, self.valeurminsizepreset3)], size=128)

        # Valeur max size Preset 1 to 2
        self.acos4 = CosTable(list=[(0, self.valeurmaxsizepreset2), (128, self.valeurmaxsizepreset3)], size=128)

        self.interpdamp2to3.play()
        
# Choix Cosinus ou lineaire
    def reverb1to2CosorLin(self, evt):
        self.oscIpad.send([0], '/coslinrev12')
        f = open(os.path.abspath("preset/reverb/ReverbPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset1 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset1 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset1 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset1 = dic["valeurmaximalesize"]

        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset2 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset2 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset2 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset2 = dic["valeurmaximalesize"]

#        if evt.GetInt() == 1:
        if self.linorcosrev1to2.GetValue() == True:
            self.oscIpad.send([1], '/coslinrev12')
        # Valeur min damp Preset 1 to 2
            self.acos = LinTable(list=[(0, self.valeurmindamppreset1), (128, self.valeurmindamppreset2)], size=128)

        # Valeur max damp Preset 1 to 2
            self.acos2 = LinTable(list=[(0, self.valeurmaxdamppreset1), (128, self.valeurmaxdamppreset2)], size=128)

        # Valeur min size Preset 1 to 2
            self.acos3 = LinTable(list=[(0, self.valeurminsizepreset1), (128, self.valeurminsizepreset2)], size=128)

        # Valeur max size Preset 1 to 2
            self.acos4 = LinTable(list=[(0, self.valeurmaxsizepreset1), (128, self.valeurmaxsizepreset2)], size=128)
            print 'Linear 1 to 2'
            
        elif self.linorcosrev1to2.GetValue() == False:
            self.oscIpad.send([0], '/coslinrev12')
            self.acos = CosTable(list=[(0, self.valeurmindamppreset1), (128, self.valeurmindamppreset2)], size=128)
            
        # Valeur max damp Preset 1 to 2
            self.acos2 = CosTable(list=[(0, self.valeurmaxdamppreset1), (128, self.valeurmaxdamppreset2)], size=128)

        # Valeur min size Preset 1 to 2
            self.acos3 = CosTable(list=[(0, self.valeurminsizepreset1), (128, self.valeurminsizepreset2)], size=128)

        # Valeur max size Preset 1 to 2
            self.acos4 = CosTable(list=[(0, self.valeurmaxsizepreset1), (128, self.valeurmaxsizepreset2)], size=128)
            print 'Cosinus 1 to 2'

    def reverb2to3CosorLin(self, evt):
        f = open(os.path.abspath("preset/reverb/ReverbPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset2 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset2 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset2 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset2 = dic["valeurmaximalesize"]

        f = open(os.path.abspath("preset/reverb/ReverbPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurmindamppreset3 = dic["valeurminimaledamp"]
        self.valeurmaxdamppreset3 = dic["valeurmaximaledamp"]
        self.valeurminsizepreset3 = dic["valeurminimalesize"]
        self.valeurmaxsizepreset3 = dic["valeurmaximalesize"]

        if self.linorcosrev2to3.GetValue() == True:
            self.oscIpad.send([1], '/coslinrev23')
        # Valeur min damp Preset 1 to 2
            self.acos = LinTable(list=[(0, self.valeurmindamppreset2), (128, self.valeurmindamppreset3)], size=128)

        # Valeur max damp Preset 1 to 2
            self.acos2 = LinTable(list=[(0, self.valeurmaxdamppreset2), (128, self.valeurmaxdamppreset3)], size=128)

        # Valeur min size Preset 1 to 2
            self.acos3 = LinTable(list=[(0, self.valeurminsizepreset2), (128, self.valeurminsizepreset3)], size=128)

        # Valeur max size Preset 1 to 2
            self.acos4 = LinTable(list=[(0, self.valeurmaxsizepreset2), (128, self.valeurmaxsizepreset3)], size=128)
            print 'Linear 2 to 3'
            
        elif self.linorcosrev2to3.GetValue() == False:
            self.oscIpad.send([0], '/coslinrev23')
            self.acos = CosTable(list=[(0, self.valeurmindamppreset2), (128, self.valeurmindamppreset3)], size=128)
            
        # Valeur max damp Preset 1 to 2
            self.acos2 = CosTable(list=[(0, self.valeurmaxdamppreset2), (128, self.valeurmaxdamppreset3)], size=128)

        # Valeur min size Preset 1 to 2
            self.acos3 = CosTable(list=[(0, self.valeurminsizepreset2), (128, self.valeurminsizepreset3)], size=128)

        # Valeur max size Preset 1 to 2
            self.acos4 = CosTable(list=[(0, self.valeurmaxsizepreset2), (128, self.valeurmaxsizepreset3)], size=128)
            print 'Cosinus 2 to 3'

    def timeInterReverb(self, value):
        x = value
        self.interreverbtime = x/128
        self.interpdamp1to2.setTime(self.interreverbtime)
        self.interpdamp2to3.setTime(self.interreverbtime)
        self.oscIpad.send([x], '/timeinterp')
        
    def presetReverb1to2(self, evt = None):
        global i
        i = i+1
        self.incrementdamp = i
        if self.incrementdamp >= 127:
            self.interpdamp1to2.stop()
            i = 0
        # Min damp 1 to 2
        self.a = self.acos.get(self.incrementdamp)
        self.aa2 = int(round(self.a))
        self.dampminimum.SetValue(self.aa2)
        self.process.valeurminimaledamp = self.aa2
        # Max Damp 1 to 2
        self.a1 = self.acos2.get(self.incrementdamp)
        self.a2 = int(round(self.a1))
        self.dampmaximum.SetValue(self.a2)
        self.process.valeurmaximaledamp = self.a2
        # Min Size 1 to 2
        self.b1 = self.acos3.get(self.incrementdamp)
        self.b2 = int(round(self.b1))
        self.sizemini.SetValue(self.b2)
        self.process.valeurminimalesize = self.b2
        # Max Size 1 to 2
        self.c1 = self.acos4.get(self.incrementdamp)
        self.c2 = int(round(self.c1))
        self.sizemaxi.SetValue(self.c2)
        self.process.valeurmaximalesize = self.c2

        self.process.updateSize()
        self.process.updateDamp()

    def presetReverb2to3(self, evt = None):
        global i
        i = i+1
        self.incrementdamp = i
        if self.incrementdamp >= 127:
            self.interpdamp2to3.stop()
            i = 0
        # Min damp 2 to 3
        self.a = self.acos.get(self.incrementdamp)
        self.aa2 = int(round(self.a))
        self.dampminimum.SetValue(self.aa2)
        self.process.valeurminimaledamp = self.aa2
        # Max Damp 2 to 3
        self.a1 = self.acos2.get(self.incrementdamp)
        self.a2 = int(round(self.a1))
        self.dampmaximum.SetValue(self.a2)
        self.process.valeurmaximaledamp = self.a2
        # Min Size 2 to 3
        self.b1 = self.acos3.get(self.incrementdamp)
        self.b2 = int(round(self.b1))
        self.sizemini.SetValue(self.b2)
        self.process.valeurminimalesize = self.b2
        # Max Size 2 to 3
        self.c1 = self.acos4.get(self.incrementdamp)
        self.c2 = int(round(self.c1))
        self.sizemaxi.SetValue(self.c2)
        self.process.valeurmaximalesize = self.c2

        self.process.updateSize()
        self.process.updateDamp()

    # Ecriture du preset 3
    def getpreset3Reverb(self, evt=None):
        dic = {"valeurminimalesize": self.process.valeurminimalesize, "valeurmaximalesize": self.process.valeurmaximalesize, "valeurminimaledamp" : self.process.valeurminimaledamp, "valeurmaximaledamp" : self.process.valeurmaximaledamp}
        f = open(os.path.abspath("preset/reverb/ReverbPreset3"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 3
    def setpreset3Reverb(self, evt=None):
        f = open(os.path.abspath("preset/reverb/ReverbPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Size
        self.process.valeurminimalesize = dic["valeurminimalesize"]
        self.sizemini.SetValue(int(dic["valeurminimalesize"]))
        self.process.valeurmaximalesize = dic["valeurmaximalesize"]
        self.sizemaxi.SetValue(int(dic["valeurmaximalesize"]))
        self.process.updateSize()

        # Preset Damp
        self.process.valeurminimaledamp = dic["valeurminimaledamp"]
        self.dampminimum.SetValue(int(dic["valeurminimaledamp"]))
        self.process.valeurmaximaledamp = dic["valeurmaximaledamp"]
        self.dampmaximum.SetValue(int(dic["valeurmaximaledamp"]))
        self.process.updateDamp()

    # Part le trig
    def startLoopingPreset(self, evt):
        self.metro.play()
        self.rand = 0
        print 'This is not random'

    # Part le trig Random
    def startLoopingPresetRandom(self, evt):
        self.metro.play()
        self.rand = 1
        print 'This is random'

    # Arrete le trig
    def stopLoopingPreset(self, evt):
        self.metro.stop()

    # Appellation des preset par le trig
    def trigPreset(self):

        # Prepare le prochain preset avec wrap around sur le nombre total de presets (total = % TOTAL)
        if self.rand == 0:
            self.presetNum = (self.presetNum + 1) % 3
        # Si Random, choisi une valeur au hasard. Il est permis d'appeller plus d'une fois de suite la meme valeur.
        if self.rand == 1:
            self.presetNum = random.choice([0, 1, 2])

        if self.presetNum == 0:
            self.setpreset1Reverb()
            print 'Trig Preset Reverb 1'

        elif self.presetNum == 1:
            self.setpreset2Reverb()
            print 'Trig Preset Reverb 2'

        elif self.presetNum == 2:
            self.setpreset3Reverb()
            print 'Trig Preset Reverb 3'

    def timeTrigReverb(self, value):
        x = value
        self.metro.time = x
        self.oscIpad.send([x], '/timepreset')

class BitReducerFrame(wx.Frame):
    def __init__(self, parent, title, pos, size, process):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)

        self.panel = wx.Panel(self)
        self.SetMinSize((350,800))
        self.panel.SetBackgroundColour("#DDDDDD")
        self.process = process

        # Ordi vers Lemur (Port Incoming, Host = Local IP Adress (celui du IPAD - Local IP Address))
        self.oscIpad = OscDataSend(types='f', port=8000, address=[
        '/bitminim', '/bitmaxim', '/beatbitmetro', '/scaleminim', '/scalemaxim', '/beatscalemetro', '/timepresetbit', '/timeinterpbit',
        '/morphbit12', '/morphbit23', '/coslinbit12', '/coslinbit23', '/presetbit1s', '/presetbit1r', '/presetbit2s', '/presetbit2r', '/presetbit3s', '/presetbit3r',
        '/seqpresetbit', '/seqpresetbitrandom', '/seqpresetbitstop'
        ], host=hostipad)
        # Lemur vers Ordi (Port Outgoing, Host = IP de l'ordi (voir pref Reseaux et changer dans TouchOSC)
        self.oscIpad2 = OscDataSend(types='f', port=8100, address=[
        '/bitminim', '/bitmaxim', '/beatbitmetro', '/scaleminim', '/scalemaxim', '/beatscalemetro', '/timepresetbit', '/timeinterpbit',
        '/morphbit12', '/morphbit23', '/coslinbit12', '/coslinbit23', '/presetbit1s', '/presetbit1r', '/presetbit2s', '/presetbit2r', '/presetbit3s', '/presetbit3r',
        '/seqpresetbit', '/seqpresetbitrandom', '/seqpresetbitstop'
        ], host=hostordi)

        self.box = wx.BoxSizer(wx.VERTICAL)

        self.sliderBox = wx.BoxSizer(wx.VERTICAL)
        self.interpolationbitBox = wx.BoxSizer(wx.HORIZONTAL)
        self.cosorlin1Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset1Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset2Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset3Box = wx.BoxSizer(wx.HORIZONTAL)
        self.preset4Box = wx.BoxSizer(wx.HORIZONTAL)

        self.panel.SetSizer(self.box)

        self.Bind(wx.EVT_CLOSE, self.bitreduceClose)

        # Trig de preset
        self.presetNum = 0
        self.metro = Metro(time=2)
        self.trigger = TrigFunc(self.metro, function=self.trigPreset)
        self.interpbit1to2 = Pattern(self.presetBit1to2, time=0.015625)
        self.interpbit2to3 = Pattern(self.presetBit2to3, time=0.015625)

        # Slider Bit Depth valeur minimale
        self.bitminiText = wx.StaticText(self.panel, id=-1, label="Bit Depth Minimum / 0")
        self.bitmini = ControlSlider(self.panel, minvalue=0, maxvalue=24, init=4, log=False, outFunction=self.bitDepthMinimum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.bitminiText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.bitmini, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Bit Depth valeur maximale
        self.bitmaxiText = wx.StaticText(self.panel, id=-1, label="Bit Depth Maximum / 24")
        self.bitmaxi = ControlSlider(self.panel, minvalue=0, maxvalue=24, init=20, log=False, outFunction=self.bitDepthMaximum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.bitmaxiText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.bitmaxi, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Beat Bit Depth
        self.beatbitText = wx.StaticText(self.panel, id=-1, label="Beat Time Bit Depth (s) / 5")
        self.beatbit = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.changeBeatBit, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.beatbitText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.beatbit, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Scale valeur minimale
        self.scaleminimumText = wx.StaticText(self.panel, id=-1, label="Scale Minimum / 100")
        self.scaleminimum = ControlSlider(self.panel, minvalue=100, maxvalue=1000, init=100, log=False, outFunction=self.scaleMinimum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.scaleminimumText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.scaleminimum, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Scale valeur maximale
        self.scalemaximumText = wx.StaticText(self.panel, id=-1, label="Scale Maximum / 1000")
        self.scalemaximum = ControlSlider(self.panel, minvalue=100, maxvalue=1000, init=500, log=False, outFunction=self.scaleMaximum, integer=True, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.scalemaximumText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.scalemaximum, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Beat Scale
        self.beatscaleText = wx.StaticText(self.panel, id=-1, label="Beat Time Scale (s) / 5")
        self.beatscale = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.changeBeatScale, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.beatscaleText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.beatscale, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Temps Trig
        self.timetrigText = wx.StaticText(self.panel, id=-1, label="Temps Preset (s) / 5")
        self.timetrig = ControlSlider(self.panel, minvalue=0.1, maxvalue=5, init=2, log=False, outFunction=self.timeTrig, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.timetrigText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.timetrig, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Temps Interpolation
        self.timeinterbitText = wx.StaticText(self.panel, id=-1, label="Temps Interpolation (s) / 10 ")
        self.timeinterbit = ControlSlider(self.panel, minvalue=1, maxvalue=10, init=2, log=False, outFunction=self.timeInterBit, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.timeinterbitText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.timeinterbit, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Preset 1 Bit Reducer
        self.preset1saveText = wx.StaticText(self.panel, id=-1, label="Preset 1")
        self.preset1saveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset1saveButton.Bind(wx.EVT_BUTTON, self.getpreset1BitReducer)
        self.preset1Box.Add(item = self.preset1saveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset1Box.Add(item = self.preset1saveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 1 Bit Reducer
        self.preset1recallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset1recallButton.Bind(wx.EVT_BUTTON, self.setpreset1BitReducer)
        self.preset1Box.Add(item = self.preset1recallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 2 Bit Reducer
        self.preset2saveText = wx.StaticText(self.panel, id=-1, label="Preset 2")
        self.preset2saveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset2saveButton.Bind(wx.EVT_BUTTON, self.getpreset2BitReducer)
        self.preset2Box.Add(item = self.preset2saveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset2Box.Add(item = self.preset2saveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 2 Bit Reducer
        self.preset2recallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset2recallButton.Bind(wx.EVT_BUTTON, self.setpreset2BitReducer)
        self.preset2Box.Add(item = self.preset2recallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 3 Bit Reducer
        self.preset3saveText = wx.StaticText(self.panel, id=-1, label="Preset 3")
        self.preset3saveButton = wx.Button(self.panel, id=-1, label="Save")
        self.preset3saveButton.Bind(wx.EVT_BUTTON, self.getpreset3BitReducer)
        self.preset3Box.Add(item = self.preset3saveText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset3Box.Add(item = self.preset3saveButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Preset 3 Bit Reducer
        self.preset3recallButton = wx.Button(self.panel, id=-1, label="Recall")
        self.preset3recallButton.Bind(wx.EVT_BUTTON, self.setpreset3BitReducer)
        self.preset3Box.Add(item = self.preset3recallButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset GO
        self.trigpresetText = wx.StaticText(self.panel, id=-1, label="Seq       ")
        self.trigpresetButton = wx.Button(self.panel, id=-1, label="Trig")
        self.trigpresetButton.Bind(wx.EVT_BUTTON, self.startLoopingPreset)
        self.preset4Box.Add(item = self.trigpresetText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.preset4Box.Add(item = self.trigpresetButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset Random GO
        self.trigpresetButtonRandom = wx.Button(self.panel, id=-1, label="Random")
        self.trigpresetButtonRandom.Bind(wx.EVT_BUTTON, self.startLoopingPresetRandom)
        self.preset4Box.Add(item = self.trigpresetButtonRandom, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Trig Preset OFF
        self.trigpresetstopButton = wx.Button(self.panel, id=-1, label="Stop")
        self.trigpresetstopButton.Bind(wx.EVT_BUTTON, self.stopLoopingPreset)
        self.preset4Box.Add(item = self.trigpresetstopButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Interpolate 1 to 2
        self.interpolatebitText = wx.StaticText(self.panel, id=-1, label="Interp   ")
        self.presetinterpolatebitButton = wx.Button(self.panel, id=-1, label="Morph 1-2")
        self.presetinterpolatebitButton.Bind(wx.EVT_BUTTON, self.interpolatePresetBit1to2)
        self.interpolationbitBox.Add(item = self.interpolatebitText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.interpolationbitBox.Add(item = self.presetinterpolatebitButton, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Interpolate 2 to 3
        self.presetinterpolatebit2Button = wx.Button(self.panel, id=-1, label="Morph 2-3")
        self.presetinterpolatebit2Button.Bind(wx.EVT_BUTTON, self.interpolatePresetBit2to3)
        self.interpolationbitBox.Add(item = self.presetinterpolatebit2Button, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Lin or Cos 1 to 2
        self.linorcosbit1to2Text = wx.StaticText(self.panel, id=-1, label="Mode   ")
        self.linorcosbit1to2 = wx.ToggleButton(self.panel, id=-1, label="Cos / Lin")
        self.linorcosbit1to2.Bind(wx.EVT_TOGGLEBUTTON, self.bit1to2CosorLin)
        self.cosorlin1Box.Add(item = self.linorcosbit1to2Text, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.cosorlin1Box.Add(item = self.linorcosbit1to2, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        # Bouton Lin or Cos 2 to 3
        self.linorcosbit2to3 = wx.ToggleButton(self.panel, id=-1, label="Cos / Lin")
        self.linorcosbit2to3.Bind(wx.EVT_TOGGLEBUTTON, self.bit2to3CosorLin)
        self.cosorlin1Box.Add(item = self.linorcosbit2to3, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 1)

        self.box.Add(item = self.sliderBox, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 20)
        self.box.Add(item = self.interpolationbitBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.cosorlin1Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset1Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset2Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset3Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)
        self.box.Add(item = self.preset4Box, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 20)

    def bitreduceClose(self, evt):
        self.Hide()

    def bitDepthMinimum(self, value):
        x = value
        self.process.valeurminimale = int(x)
        self.process.updateSequence()
        self.oscIpad.send([x], '/bitminim')

    def bitDepthMaximum(self, value):
        x = value
        self.process.valeurmaximale = int(x)
        self.process.updateSequence()
        self.oscIpad.send([x], '/bitmaxim')

    def scaleMinimum(self, value):
        x = value
        self.process.valeurminimalescale = int(x)
        self.process.updateScale()
        self.oscIpad.send([x], '/scaleminim')
    def scaleMaximum(self, value):
        x = value
        self.process.valeurmaximalescale = int(x)
        self.process.updateScale()
        self.oscIpad.send([x], '/scalemaxim')

    def changeBeatScale(self, value):
        x = value
        self.process.updateBeatScale(x)
        self.oscIpad.send([x], '/beatscalemetro')

    def changeBeatBit(self, value):
        x = value
        self.process.updateBeatBit(x)
        self.oscIpad.send([x], '/beatbitmetro')

    # Gestion de preset du bit reducer / Les metronomes ne sont pas inclus dans les preset... choix personnel

    # Ecriture du preset 1
    def getpreset1BitReducer(self, evt=None):
        dic = {"valeurminimalebit": self.process.valeurminimale, "valeurmaximalebit": self.process.valeurmaximale, "valeurminimalescale" : self.process.valeurminimalescale, "valeurmaximalescale" : self.process.valeurmaximalescale}
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset1"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 1
    def setpreset1BitReducer(self, evt=None):
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Bit
        self.process.valeurminimale = dic["valeurminimalebit"]
        self.bitmini.SetValue(int(dic["valeurminimalebit"]))
        self.process.valeurmaximale = dic["valeurmaximalebit"]
        self.bitmaxi.SetValue(int(dic["valeurmaximalebit"]))
        self.process.updateSequence()

        # Preset Scale
        self.process.valeurminimalescale = dic["valeurminimalescale"]
        self.scaleminimum.SetValue(int(dic["valeurminimalescale"]))
        self.process.valeurmaximalescale = dic["valeurmaximalescale"]
        self.scalemaximum.SetValue(int(dic["valeurmaximalescale"]))
        self.process.updateScale()

    # Ecriture du preset 2
    def getpreset2BitReducer(self, evt=None):
        dic = {"valeurminimalebit": self.process.valeurminimale, "valeurmaximalebit": self.process.valeurmaximale, "valeurminimalescale" : self.process.valeurminimalescale, "valeurmaximalescale" : self.process.valeurmaximalescale}
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 2
    def setpreset2BitReducer(self, evt=None):
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Bit
        self.process.valeurminimale = dic["valeurminimalebit"]
        self.bitmini.SetValue(int(dic["valeurminimalebit"]))
        self.process.valeurmaximale = dic["valeurmaximalebit"]
        self.bitmaxi.SetValue(int(dic["valeurmaximalebit"]))
        self.process.updateSequence()

        # Preset Scale
        self.process.valeurminimalescale = dic["valeurminimalescale"]
        self.scaleminimum.SetValue(int(dic["valeurminimalescale"]))
        self.process.valeurmaximalescale = dic["valeurmaximalescale"]
        self.scalemaximum.SetValue(int(dic["valeurmaximalescale"]))
        self.process.updateScale()

    # Ecriture du preset 3
    def getpreset3BitReducer(self, evt=None):
        dic = {"valeurminimalebit": self.process.valeurminimale, "valeurmaximalebit": self.process.valeurmaximale, "valeurminimalescale" : self.process.valeurminimalescale, "valeurmaximalescale" : self.process.valeurmaximalescale}
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset3"), "w")
        f.write(str(dic))
        f.close()

    # Lecture du preset 3
    def setpreset3BitReducer(self, evt=None):
        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)

        # Preset Bit
        self.process.valeurminimale = dic["valeurminimalebit"]
        self.bitmini.SetValue(int(dic["valeurminimalebit"]))
        self.process.valeurmaximale = dic["valeurmaximalebit"]
        self.bitmaxi.SetValue(int(dic["valeurmaximalebit"]))
        self.process.updateSequence()

        # Preset Scale
        self.process.valeurminimalescale = dic["valeurminimalescale"]
        self.scaleminimum.SetValue(int(dic["valeurminimalescale"]))
        self.process.valeurmaximalescale = dic["valeurmaximalescale"]
        self.scalemaximum.SetValue(int(dic["valeurmaximalescale"]))
        self.process.updateScale()

    def interpolatePresetBit1to2(self, evt):

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset1 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset1 = dic["valeurmaximalebit"]
        self.valeurminscalepreset1 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset1 = dic["valeurmaximalescale"]

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset2 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset2 = dic["valeurmaximalebit"]
        self.valeurminscalepreset2 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset2 = dic["valeurmaximalescale"]

        # Valeur min bit Preset 1 to 2
        self.acos = CosTable(list=[(0, self.valeurminbitpreset1), (128, self.valeurminbitpreset2)], size=128)

        # Valeur max bit Preset 1 to 2
        self.acos2 = CosTable(list=[(0, self.valeurmaxbitpreset1), (128, self.valeurmaxbitpreset2)], size=128)

        # Valeur min scale Preset 1 to 2
        self.acos3 = CosTable(list=[(0, self.valeurminscalepreset1), (128, self.valeurminscalepreset2)], size=128)

        # Valeur max scale Preset 1 to 2
        self.acos4 = CosTable(list=[(0, self.valeurmaxscalepreset1), (128, self.valeurmaxscalepreset2)], size=128)

        self.interpbit1to2.play()

    def interpolatePresetBit2to3(self, evt):

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset2 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset2 = dic["valeurmaximalebit"]
        self.valeurminscalepreset2 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset2 = dic["valeurmaximalescale"]

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset3 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset3 = dic["valeurmaximalebit"]
        self.valeurminscalepreset3 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset3 = dic["valeurmaximalescale"]

        # Valeur min bit Preset 2 to 3
        self.acos = CosTable(list=[(0, self.valeurminbitpreset2), (128, self.valeurminbitpreset3)], size=128)

        # Valeur max bit Preset 2 to 3
        self.acos2 = CosTable(list=[(0, self.valeurmaxbitpreset2), (128, self.valeurmaxbitpreset3)], size=128)

        # Valeur min scale Preset 2 to 3
        self.acos3 = CosTable(list=[(0, self.valeurminscalepreset2), (128, self.valeurminscalepreset3)], size=128)

        # Valeur max scale Preset 2 to 3
        self.acos4 = CosTable(list=[(0, self.valeurmaxscalepreset2), (128, self.valeurmaxscalepreset3)], size=128)

        self.interpbit2to3.play()

    def bit1to2CosorLin(self, evt):

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset1"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset1 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset1 = dic["valeurmaximalebit"]
        self.valeurminscalepreset1 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset1 = dic["valeurmaximalescale"]

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset2 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset2 = dic["valeurmaximalebit"]
        self.valeurminscalepreset2 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset2 = dic["valeurmaximalescale"]

        if self.linorcosbit1to2.GetValue() == True:
            self.oscIpad.send([1], '/coslinbit12')

        # Valeur min bit Preset 1 to 2
            self.acos = LinTable(list=[(0, self.valeurminbitpreset1), (128, self.valeurminbitpreset2)], size=128)
        # Valeur max bit Preset 1 to 2
            self.acos2 = LinTable(list=[(0, self.valeurmaxbitpreset1), (128, self.valeurmaxbitpreset2)], size=128)

        # Valeur min scale Preset 1 to 2
            self.acos3 = LinTable(list=[(0, self.valeurminscalepreset1), (128, self.valeurminscalepreset2)], size=128)

        # Valeur max scale Preset 1 to 2
            self.acos4 = LinTable(list=[(0, self.valeurmaxscalepreset1), (128, self.valeurmaxscalepreset2)], size=128)
            print 'Linear 1 to 2'

        elif self.linorcosbit1to2.GetValue() == False:
            self.oscIpad.send([0], '/coslinbit12')

        # Valeur min bit Preset 1 to 2
            self.acos = CosTable(list=[(0, self.valeurminbitpreset1), (128, self.valeurminbitpreset2)], size=128)

        # Valeur max bit Preset 1 to 2
            self.acos2 = CosTable(list=[(0, self.valeurmaxbitpreset1), (128, self.valeurmaxbitpreset2)], size=128)

        # Valeur min scale Preset 1 to 2
            self.acos3 = CosTable(list=[(0, self.valeurminscalepreset1), (128, self.valeurminscalepreset2)], size=128)

        # Valeur max scale Preset 1 to 2
            self.acos4 = CosTable(list=[(0, self.valeurmaxscalepreset1), (128, self.valeurmaxscalepreset2)], size=128)
            print 'Cosinus 1 to 2'

    def bit2to3CosorLin(self, evt):

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset2"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset2 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset2 = dic["valeurmaximalebit"]
        self.valeurminscalepreset2 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset2 = dic["valeurmaximalescale"]

        f = open(os.path.abspath("preset/bitreduce/BitReducerPreset3"), "r")
        text = f.read()
        f.close()
        dic = eval(text)
        self.valeurminbitpreset3 = dic["valeurminimalebit"]
        self.valeurmaxbitpreset3 = dic["valeurmaximalebit"]
        self.valeurminscalepreset3 = dic["valeurminimalescale"]
        self.valeurmaxscalepreset3 = dic["valeurmaximalescale"]

        if self.linorcosbit2to3.GetValue() == True:
            self.oscIpad.send([1], '/coslinbit23')
        # Valeur min bit Preset 2 to 3
            self.acos = LinTable(list=[(0, self.valeurminbitpreset2), (128, self.valeurminbitpreset3)], size=128)
        # Valeur max bit Preset 2 to 3
            self.acos2 = LinTable(list=[(0, self.valeurmaxbitpreset2), (128, self.valeurmaxbitpreset3)], size=128)

        # Valeur min scale Preset 1 to 2
            self.acos3 = LinTable(list=[(0, self.valeurminscalepreset2), (128, self.valeurminscalepreset3)], size=128)

        # Valeur max scale Preset 1 to 2
            self.acos4 = LinTable(list=[(0, self.valeurmaxscalepreset2), (128, self.valeurmaxscalepreset3)], size=128)
            print 'Linear 2 to 3'

        elif self.linorcosbit2to3.GetValue() == False:
            self.oscIpad.send([0], '/coslinbit23')

        # Valeur min bit Preset 1 to 2
            self.acos = CosTable(list=[(0, self.valeurminbitpreset2), (128, self.valeurminbitpreset3)], size=128)

        # Valeur max bit Preset 1 to 2
            self.acos2 = CosTable(list=[(0, self.valeurmaxbitpreset2), (128, self.valeurmaxbitpreset3)], size=128)

        # Valeur min scale Preset 1 to 2
            self.acos3 = CosTable(list=[(0, self.valeurminscalepreset2), (128, self.valeurminscalepreset3)], size=128)

        # Valeur max scale Preset 1 to 2
            self.acos4 = CosTable(list=[(0, self.valeurmaxscalepreset2), (128, self.valeurmaxscalepreset3)], size=128)
            print 'Cosinus 2 to 3'

    def timeInterBit(self, value):
        x = value
        self.interbittime = x/128
        self.interpbit1to2.setTime(self.interbittime)
        self.interpbit2to3.setTime(self.interbittime)
        self.oscIpad.send([x], '/timeinterpbit')

    def presetBit1to2(self, evt = None):
        global i1
        i1 = i1+1
        self.incrementbit = i1
        if self.incrementbit >= 127:
            self.interpbit1to2.stop()
            i1 = 0
        # Min bit 1 to 2
        self.a = self.acos.get(self.incrementbit)
        self.aa2 = int(round(self.a))
        self.bitmini.SetValue(self.aa2)
        self.process.valeurminimale = self.aa2
        # Max bit 1 to 2
        self.a1 = self.acos2.get(self.incrementbit)
        self.a2 = int(round(self.a1))
        self.bitmaxi.SetValue(self.a2)
        self.process.valeurmaximale = self.a2
        # Min Scale 1 to 2
        self.b1 = self.acos3.get(self.incrementbit)
        self.b2 = int(round(self.b1))
        self.scaleminimum.SetValue(self.b2)
        self.process.valeurminimalescale = self.b2
        # Max Scale 1 to 2
        self.c1 = self.acos4.get(self.incrementbit)
        self.c2 = int(round(self.c1))
        self.scalemaximum.SetValue(self.c2)
        self.process.valeurmaximalescale = self.c2

        self.process.updateScale()
        self.process.updateSequence()

    def presetBit2to3(self, evt = None):
        global i1
        i1 = i1+1
        self.incrementbit = i1
        if self.incrementbit >= 127:
            self.interpbit2to3.stop()
            i1 = 0
        # Min bit 1 to 2
        self.a = self.acos.get(self.incrementbit)
        self.aa2 = int(round(self.a))
        self.bitmini.SetValue(self.aa2)
        self.process.valeurminimale = self.aa2
        # Max bit 1 to 2
        self.a1 = self.acos2.get(self.incrementbit)
        self.a2 = int(round(self.a1))
        self.bitmaxi.SetValue(self.a2)
        self.process.valeurmaximale = self.a2
        # Min Scale 1 to 2
        self.b1 = self.acos3.get(self.incrementbit)
        self.b2 = int(round(self.b1))
        self.scaleminimum.SetValue(self.b2)
        self.process.valeurminimalescale = self.b2
        # Max Scale 1 to 2
        self.c1 = self.acos4.get(self.incrementbit)
        self.c2 = int(round(self.c1))
        self.scalemaximum.SetValue(self.c2)
        self.process.valeurmaximalescale = self.c2

        self.process.updateScale()
        self.process.updateSequence()

    # Part le trig
    def startLoopingPreset(self, evt):
        self.metro.play()
        self.rand = 0
        print 'This is not random'

    # Part le trig Random
    def startLoopingPresetRandom(self, evt):
        self.metro.play()
        self.rand = 1
        print 'This is random'

    # Arrete le trig
    def stopLoopingPreset(self, evt):
        self.metro.stop()

    # Appellation des preset par le trig
    def trigPreset(self):

        # Prepare le prochain preset avec wrap around sur le nombre total de presets (total = % TOTAL)
        if self.rand == 0:
            self.presetNum = (self.presetNum + 1) % 3
        # Si Random, choisi une valeur au hasard. Il est permis d'appeller plus d'une fois de suite la meme valeur.
        if self.rand == 1:
            self.presetNum = random.choice([0, 1, 2])

        if self.presetNum == 0:
            self.setpreset1BitReducer()
            print 'Trig Preset Bit Reducer 1'

        elif self.presetNum == 1:
            self.setpreset2BitReducer()
            print 'Trig Preset Bit Reducer 2'

        elif self.presetNum == 2:
            self.setpreset3BitReducer()
            print 'Trig Preset Bit Reducer 3'

    def timeTrig(self, value):
        x = value
        self.metro.time = x
        self.oscIpad.send([x], '/timepresetbit')

class MixeurFrame(wx.Frame):
    def __init__(self, parent, title, pos, size, process):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)
        self.panel = wx.Panel(self)
        self.SetMinSize((240,800))
        self.panel.SetBackgroundColour("#DDDDDD")
        self.mixeur = mixeur

        self.box = wx.BoxSizer(wx.VERTICAL)
        self.ramBox = wx.BoxSizer(wx.VERTICAL)
        self.inputBox = wx.BoxSizer(wx.VERTICAL)
        self.loopBox = wx.BoxSizer(wx.VERTICAL)

        # Ordi vers Lemur (Port Incoming, Host = Local IP Adress (celui du IPAD - Local IP Address))
        self.oscIpad = OscDataSend(types='f', port=8000, address=['/ramdirect', '/rambitreduce', '/ramreverb', '/rambrreverb', '/ramreverbbr',
        '/indirect', '/inbitreduce', '/inreverb', '/inbrreverb', '/inreverbbr',
        '/loopdirect', '/loopbitreduce', '/loopreverb', '/loopbrreverb', '/loopreverbbr'], host=hostipad)
        # Lemur vers Ordi (Port Outgoing, Host = IP de l'ordi (voir pref Reseaux et changer dans TouchOSC)
        self.oscIpad2 = OscDataSend(types='f', port=8100, address=['/ramdirect', '/rambitreduce', '/ramreverb', '/rambrreverb', '/ramreverbbr',
        '/indirect', '/inbitreduce', '/inreverb', '/inbrreverb', '/inreverbbr',
        '/loopdirect', '/loopbitreduce', '/loopreverb', '/loopbrreverb', '/loopreverbbr'], host=hostordi)

        self.panel.SetSizer(self.box)

        self.Bind(wx.EVT_CLOSE, self.mixeurClose)

        # Slider Volume Son Ram Direct Out
        self.volumeramdirectText = wx.StaticText(self.panel, id=-1, label="Volume Son Ram Direct / 1")
        self.volumeramdirect = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeRamDirect, integer=False, powoftwo=False, backColour=None)
        self.ramBox.Add(item = self.volumeramdirectText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.ramBox.Add(item = self.volumeramdirect, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Son Ram Bit Reducer
        self.volumerambitreduceText = wx.StaticText(self.panel, id=-1, label="Volume Son Ram Bit Reducer / 1")
        self.volumerambitreduce = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeRamBit, integer=False, powoftwo=False, backColour=None)
        self.ramBox.Add(item = self.volumerambitreduceText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.ramBox.Add(item = self.volumerambitreduce, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Son Ram Reverb
        self.volumeramdelaiText = wx.StaticText(self.panel, id=-1, label="Volume Son Ram Reverb / 1")
        self.volumeramdelais = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeRamDelai, integer=False, powoftwo=False, backColour=None)
        self.ramBox.Add(item = self.volumeramdelaiText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.ramBox.Add(item = self.volumeramdelais, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Son Ram BR dans Reverb
        self.volumebrdelaiText = wx.StaticText(self.panel, id=-1, label="Volume Son Ram BR dans Reverb / 1")
        self.volumebrdelais = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeBitReduceDansDelai, integer=False, powoftwo=False, backColour=None)
        self.ramBox.Add(item = self.volumebrdelaiText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.ramBox.Add(item = self.volumebrdelais, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Son Ram Reverb dans BR
        self.volumereverbbrText = wx.StaticText(self.panel, id=-1, label="Volume Son Ram Reverb dans BR / 1")
        self.volumereverbbre = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeReverbDansBitReduce, integer=False, powoftwo=False, backColour=None)
        self.ramBox.Add(item = self.volumereverbbrText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.ramBox.Add(item = self.volumereverbbre, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Entree 1 Direct Out
        self.volumeentree1directText = wx.StaticText(self.panel, id=-1, label="Volume Entree 1 Direct / 1")
        self.volumeentree1direct = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeEntree1Direct, integer=False, powoftwo=False, backColour=None)
        self.inputBox.Add(item = self.volumeentree1directText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.inputBox.Add(item = self.volumeentree1direct, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Entree 1 Bit Reducer
        self.volumeentree1bitreduceText = wx.StaticText(self.panel, id=-1, label="Volume Entree 1 Bit Reducer / 1")
        self.volumeentree1bitreduces = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeEntree1Bit, integer=False, powoftwo=False, backColour=None)
        self.inputBox.Add(item = self.volumeentree1bitreduceText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.inputBox.Add(item = self.volumeentree1bitreduces, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Entree 1 Reverb
        self.volumeentree1delaiText = wx.StaticText(self.panel, id=-1, label="Volume Entree 1 Reverb / 1")
        self.volumeentree1delais = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeEntree1Delai, integer=False, powoftwo=False, backColour=None)
        self.inputBox.Add(item = self.volumeentree1delaiText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.inputBox.Add(item = self.volumeentree1delais, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Entree1 Ram BR dans Reverb
        self.volumebrdelaiinText = wx.StaticText(self.panel, id=-1, label="Volume Entree 1 BR dans Reverb / 1")
        self.volumebrdelaiins = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeBitReduceDansDelaiin, integer=False, powoftwo=False, backColour=None)
        self.inputBox.Add(item = self.volumebrdelaiinText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.inputBox.Add(item = self.volumebrdelaiins, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Entree1 Reverb dans BR
        self.volumereverbbrinText = wx.StaticText(self.panel, id=-1, label="Volume Entree 1 Reverb dans BR / 1")
        self.volumereverbbrins = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeReverbDansBitReducein, integer=False, powoftwo=False, backColour=None)
        self.inputBox.Add(item = self.volumereverbbrinText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.inputBox.Add(item = self.volumereverbbrins, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Loop Direct Out
        self.volumeloopdirectText = wx.StaticText(self.panel, id=-1, label="Volume Loop Direct / 1")
        self.volumeloopdirects = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeLoopDirect, integer=False, powoftwo=False, backColour=None)
        self.loopBox.Add(item = self.volumeloopdirectText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.loopBox.Add(item = self.volumeloopdirects, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Loop Bit Reduce
        self.volumeloopbitreduceText = wx.StaticText(self.panel, id=-1, label="Volume Loop Bit Reducer / 1")
        self.volumeloopbitreduces = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeLoopBitreduce, integer=False, powoftwo=False, backColour=None)
        self.loopBox.Add(item = self.volumeloopbitreduceText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.loopBox.Add(item = self.volumeloopbitreduces, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Loop Reverb
        self.volumeloopreverbText = wx.StaticText(self.panel, id=-1, label="Volume Loop Reverb / 1")
        self.volumeloopreverbs = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeLoopReverb, integer=False, powoftwo=False, backColour=None)
        self.loopBox.Add(item = self.volumeloopreverbText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.loopBox.Add(item = self.volumeloopreverbs, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Loop Bit Reduce dans Reverb
        self.volumeloopbrinreverbText = wx.StaticText(self.panel, id=-1, label="Volume Loop BR dans Reverb / 1")
        self.volumeloopbrinreverbs = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeBitReduceDansDelaiLoop, integer=False, powoftwo=False, backColour=None)
        self.loopBox.Add(item = self.volumeloopbrinreverbText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.loopBox.Add(item = self.volumeloopbrinreverbs, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        # Slider Volume Loop Bit Reduce dans Reverb
        self.volumelooppreverbinbrText = wx.StaticText(self.panel, id=-1, label="Volume Loop Reverb dans BR / 1")
        self.volumelooppreverbinbr = ControlSlider(self.panel, minvalue=0.00, maxvalue=1, init= 0.00, log=False, outFunction=self.volumeReverbdansBRLoop, integer=False, powoftwo=False, backColour=None)
        self.loopBox.Add(item = self.volumelooppreverbinbrText, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)
        self.loopBox.Add(item = self.volumelooppreverbinbr, flag = wx.EXPAND|wx.ALL, border = 0, proportion = 0)

        self.box.Add(item = self.ramBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 10)
        self.box.Add(item = self.inputBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 10)
        self.box.Add(item = self.loopBox, proportion = 1, flag = wx.EXPAND|wx.TOP, border = 10)

    def mixeurClose(self, evt):
        self.Hide()

    # Volume Son Ram Direct Out
    def volumeRamDirect(self, value):
        x = value
        self.ramdirectout = x
        self.mixeur.mm.setAmp(0, 0, self.ramdirectout)
        self.oscIpad.send([x], '/ramdirect')

    # Volume Entree 1 Direct Out
    def volumeEntree1Direct(self, value):
        x = value
        self.entree1directout = x
        self.mixeur.mm.setAmp(1, 0, self.entree1directout)
        self.oscIpad.send([x], '/indirect')
    # Volume Son Ram Bit Reducer
    def volumeRamBit(self, value):
        x = value
        self.volumerambit = x
        self.mixeur.mm.setAmp(0, 1, self.volumerambit)
        self.oscIpad.send([x], '/rambitreduce')
    # Volume Entree 1 Bit Reducer
    def volumeEntree1Bit(self, value):
        x = value
        self.volumeentree1bitreduce = x
        self.mixeur.mm.setAmp(1, 1, self.volumeentree1bitreduce)
        self.oscIpad.send([x], '/inbitreduce')
    # Volume Son Ram Delai
    def volumeRamDelai(self, value):
        x = value
        self.volumeramdelai = x
        self.mixeur.mm.setAmp(0, 2, self.volumeramdelai)
        self.oscIpad.send([x], '/ramreverb')

    # Volume Entree 1 Delai
    def volumeEntree1Delai(self, value):
        x = value
        self.volumeentree1delai = x
        self.mixeur.mm.setAmp(1, 2, self.volumeentree1delai)
        self.oscIpad.send([x], '/inreverb')

    # Volume Br dans Reverb Son Ram
    def volumeBitReduceDansDelai(self, value):
        x = value
        self.volumebrdelai = x
        self.volumerambit = x
        self.mixeur.mm.setAmp(0, 1, self.volumerambit)
        self.mixeur.mm.setAmp(2, 2, self.volumebrdelai)
        self.oscIpad.send([x], '/rambrreverb')

    # Volume Reverb dans BR Son Ram
    def volumeReverbDansBitReduce(self, value):
        x = value
        self.volumereverbbr = x
        self.volumeramdelai = x
        self.mixeur.mm.setAmp(0, 2, self.volumeramdelai)
        self.mixeur.mm.setAmp(3, 1, self.volumereverbbr)
        self.oscIpad.send([x], '/ramreverbbr')

    # Volume Br dans Reverb Entree 1
    def volumeBitReduceDansDelaiin(self, value):
        x = value
        self.volumebrdelaiin = x
        self.volumeentree1bitreduce = x
        self.mixeur.mm.setAmp(1, 1, self.volumeentree1bitreduce)
        self.mixeur.mm.setAmp(2, 2, self.volumebrdelaiin)
        self.oscIpad.send([x], '/inbrreverb')

    # Volume Reverb dans Br Entree 1
    def volumeReverbDansBitReducein(self, value):
        x = value
        self.volumereverbbrin = x
        self.volumeentree1delai = x
        self.mixeur.mm.setAmp(1, 2, self.volumeentree1delai)
        self.mixeur.mm.setAmp(3, 1, self.volumereverbbrin)
        self.oscIpad.send([x], '/inreverbbr')

    # Volume Loop dans Direct Out
    def volumeLoopDirect(self, value):
        x = value
        self.volumeloopdirect = x
        self.mixeur.mm.setAmp(4, 0, self.volumeloopdirect)
        self.oscIpad.send([x], '/loopdirect')
    def volumeLoopBitreduce(self, value):
        x = value
        self.volumeloopbitreduce = x
        self.mixeur.mm.setAmp(4, 1, self.volumeloopbitreduce)
        self.oscIpad.send([x], '/loopbitreduce')
    def volumeLoopReverb(self, value):
        x = value
        self.volumeloopreverb = x
        self.mixeur.mm.setAmp(4, 2, self.volumeloopreverb)
        self.oscIpad.send([x], '/loopreverb')
    # Volume Br dans Reverb Loop
    def volumeBitReduceDansDelaiLoop(self, value):
        x = value
        self.volumereverbbrloop = x
        self.volumeloopreverb = x
        self.mixeur.mm.setAmp(4, 2, self.volumeloopreverb)
        self.mixeur.mm.setAmp(2, 2, self.volumereverbbrloop)
        self.oscIpad.send([x], '/loopbrreverb')
    # Volume Reverb dans BR Loop
    def volumeReverbdansBRLoop(self, value):
        x = value
        self.volumebrdelailoop = x
        self.volumeloopbitreduce = x
        self.mixeur.mm.setAmp(4, 1, self.volumeloopbitreduce)
        self.mixeur.mm.setAmp(2, 2, self.volumebrdelailoop)
        self.oscIpad.send([x], '/loopreverbbr')

class LoopingFrame(wx.Frame):
    def __init__(self, parent, title, pos, size, process):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)
        self.SetMinSize((250, 800))
        self.audio = audio
        self.process = process
        self.maxdur = 8

        # Ordi vers Lemur (Port Incoming, Host = Local IP Adress (celui du IPAD - Local IP Address))
        self.oscIpad = OscDataSend(types='f', port=8000, address=['/looppitch', '/looppitchmetro', '/loopstart', '/loopstartmetro', '/loopend', '/loopendmetro',
         '/looprec', '/loopoverdub', '/loopmute', '/loopmuteafplay', '/loopplay', '/looperase', '/loopreverse', '/looprandompitch', '/looprandomend', '/looprandomstart'], host=hostipad)
        # Lemur vers Ordi (Port Outgoing, Host = IP de l'ordi (voir pref Reseaux et changer dans TouchOSC)
        self.oscIpad2 = OscDataSend(types='f', port=8100, address=['/looppitch', '/looppitchmetro', '/loopstart', '/loopstartmetro', '/loopend', '/loopendmetro',
         '/looprec', '/loopoverdub', '/loopmute', '/loopmuteafplay', '/loopplay', '/looperase', '/loopreverse', '/looprandompitch', '/looprandomend', '/looprandomstart'], host=hostordi)

        self.metro = Metro(time=2)
        self.trigger = TrigFunc(self.metro, function=self.trigPitch)

        self.metro2 = Metro(time=2)
        self.trigger2 = TrigFunc(self.metro2, function=self.trigDur)

        self.metro3 = Metro(time=2)
        self.trigger3 = TrigFunc(self.metro3, function=self.trigStart)

        # Panneau principal
        self.panel = wx.Panel(self)

        # Gestion dynamique de l'espace
        self.box = wx.BoxSizer(wx.VERTICAL)

        # On assigne la boite au panneau principal
        self.panel.SetSizer(self.box)

        # Ajout d'une boite dans une boite
        self.buttonBox = wx.BoxSizer(wx.VERTICAL)
        self.sliderBox = wx.BoxSizer(wx.VERTICAL)

        self.Bind(wx.EVT_CLOSE, self.looperClose)
        # Menu pour l'entree du looper - Si pas de carte de son, 2 entree (donc Input 3-4 ne marche pas), si carte de son, tout marche
        fxs = ['Input 1', 'Input 2', 'Input 3', 'Input 4']
        self.popup = wx.Choice(self.panel, id=-1, choices=fxs)
        self.buttonBox.Add(item = self.popup, flag = wx.EXPAND|wx.ALL, border = 10, proportion = 0)
        self.popup.Bind(wx.EVT_CHOICE, self.changeInputLoop)

        # Bouton Record Loop
        self.recordloop = wx.ToggleButton(self.panel, id=-1, label="Record On / Off - Loop 1")
        self.recordloop.SetBackgroundColour(wx.Colour(255, 0, 0))
        self.recordloop.Bind(wx.EVT_TOGGLEBUTTON, self.recordLoop)
        self.buttonBox.Add(item = self.recordloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Overdub
        self.overdubloop = wx.Button(self.panel, id=-1, label="Overdub")
        self.overdubloop.Bind(wx.EVT_BUTTON, self.overdubLoop1)
        self.buttonBox.Add(item = self.overdubloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Mute
        self.killloop = wx.Button(self.panel, id=-1, label="Mute Loop 1")
        self.killloop.Bind(wx.EVT_BUTTON, self.killLoop1)
        self.buttonBox.Add(item = self.killloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton  Mute After Play
        self.killaploop = wx.Button(self.panel, id=-1, label="Mute After Play Loop 1")
        self.killaploop.Bind(wx.EVT_BUTTON, self.killafterplayLoop1)
        self.buttonBox.Add(item = self.killaploop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Play
        self.playloop = wx.Button(self.panel, id=-1, label="Play")
        self.playloop.SetBackgroundColour(wx.Colour(0, 255, 0))
        self.playloop.Bind(wx.EVT_BUTTON, self.playLoop1)
        self.buttonBox.Add(item = self.playloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Erase
        self.eraseloop = wx.Button(self.panel, id=-1, label="Erase")
        self.eraseloop.SetBackgroundColour(wx.Colour(0, 0, 255))
        self.eraseloop.Bind(wx.EVT_BUTTON, self.eraseLoop1)
        self.buttonBox.Add(item = self.eraseloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Reverse Loop
        self.reverseloop = wx.ToggleButton(self.panel, id=-1, label="Reverse")
        self.reverseloop.Bind(wx.EVT_TOGGLEBUTTON, self.reverseLoop)
        self.buttonBox.Add(item = self.reverseloop, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Randomize Pitch
        self.randompitch = wx.ToggleButton(self.panel, id=-1, label="Randomize Pitch / Octave")
        self.randompitch.Bind(wx.EVT_TOGGLEBUTTON, self.pitchRandom)
        self.buttonBox.Add(item = self.randompitch, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Randomize Dur
        self.randomdur = wx.ToggleButton(self.panel, id=-1, label="Randomize End")
        self.randomdur.Bind(wx.EVT_TOGGLEBUTTON, self.durRandom)
        self.buttonBox.Add(item = self.randomdur, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Bouton Randomize Start
        self.randomstart = wx.ToggleButton(self.panel, id=-1, label="Randomize Start")
        self.randomstart.Bind(wx.EVT_TOGGLEBUTTON, self.startRandom)
        self.buttonBox.Add(item = self.randomstart, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Loop Record Pitch
        self.changelooppitchText = wx.StaticText(self.panel, id=-1, label=" Pitch Loop / 4")
        self.changelooppitch = ControlSlider(self.panel, minvalue=0.1, maxvalue=4, init=1, log=False, outFunction=self.changeLoopPitch, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changelooppitchText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changelooppitch, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Time Metro Random Pitch
        self.changemetropitchText = wx.StaticText(self.panel, id=-1, label=" Metro Pitch / 8")
        self.changemetropitch = ControlSlider(self.panel, minvalue=0.1, maxvalue=4, init=1, log=False, outFunction=self.changeLoopMetroPitch, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changemetropitchText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changemetropitch, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Loop Record Start
        self.changeloopstartText = wx.StaticText(self.panel, id=-1, label="Loop Start")
        self.changeloopstart = ControlSlider(self.panel, minvalue=0., maxvalue=self.maxdur, init=0., log=False, outFunction=self.changeLoopStart, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changeloopstartText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changeloopstart, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Time Metro Random End
        self.changemetrostartText = wx.StaticText(self.panel, id=-1, label=" Metro Start / 8")
        self.changemetrostart = ControlSlider(self.panel, minvalue=0.1, maxvalue=self.maxdur, init=8, log=False, outFunction=self.changeLoopMetroStart, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changemetrostartText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changemetrostart, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Loop Record End
        self.changeloopdurText = wx.StaticText(self.panel, id=-1, label=" Loop End")
        self.changeloopdur = ControlSlider(self.panel, minvalue=0.1, maxvalue=self.maxdur, init=8, log=False, outFunction=self.changeLoopDur, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changeloopdurText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changeloopdur, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        # Slider Time Metro Random End
        self.changemetrodurText = wx.StaticText(self.panel, id=-1, label=" Metro End / 8")
        self.changemetrodur = ControlSlider(self.panel, minvalue=0.1, maxvalue=self.maxdur, init=8, log=False, outFunction=self.changeLoopMetroDur, integer=False, powoftwo=False, backColour=None)
        self.sliderBox.Add(item = self.changemetrodurText, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)
        self.sliderBox.Add(item = self.changemetrodur, flag = wx.EXPAND|wx.ALL, border = 5, proportion = 0)

        self.box.Add(item = self.sliderBox, proportion = 0, flag = wx.EXPAND|wx.BOTTOM, border = 20)
        self.box.Add(item = self.buttonBox, proportion = 0, flag = wx.EXPAND|wx.ALL, border = 20)

    def looperClose(self, evt):
        self.Hide()

    def changeLoopMetroPitch(self, value):
        x = value
        self.metro.time = x
        self.oscIpad.send([x], '/looppitchmetro')

    def changeLoopMetroDur(self, value):
        x = value
        self.metro2.time = x
        self.oscIpad.send([x], '/loopendmetro')

    def changeLoopMetroStart(self, value):
        x = value
        self.metro3.time = x
        self.oscIpad.send([x], '/loopstartmetro')

    def pitchRandom(self, evt):
        if self.randompitch.GetValue() == False:
            self.oscIpad.send([0], '/looprandompitch')
            self.metro.stop()
            self.audio.looprec.pitch = 1
            self.changelooppitch.SetValue(int(1))
            print 'No Random'
        elif self.randompitch.GetValue() == True:
            self.oscIpad.send([1], '/looprandompitch')
            self.metro.play()

    def durRandom(self, evt):
        if self.randomdur.GetValue() == False:
            self.oscIpad.send([0], '/looprandomend')
            self.metro2.stop()
            self.audio.looprec.dur = self.maxdur
            self.changeloopdur.SetValue(self.maxdur)
            print 'No Random'
        elif self.randomdur.GetValue() == True:
            self.oscIpad.send([1], '/looprandomend')
            self.metro2.play()

    def startRandom(self, evt):
        if self.randomstart.GetValue() == False:
            self.oscIpad.send([0], '/looprandomstart')
            self.metro3.stop()
            self.audio.looprec.start = self.maxdur
            self.changeloopstart.SetValue(self.maxdur)
            print 'No Random'
        elif self.randomstart.GetValue() == True:
            self.oscIpad.send([1], '/looprandomstart')
            self.metro3.play()

    def trigPitch(self):
        freqrandompitch = random.choice([0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4])
        self.audio.looprec.pitch = freqrandompitch
        self.changelooppitch.SetValue(freqrandompitch)
        print 'Random Pitch'

    def trigDur(self):
        durrandomloop = random.uniform(0, self.maxdur)
        self.audio.looprec.dur = durrandomloop
        self.changeloopdur.SetValue(durrandomloop)
        print 'Random Dur'

    def trigStart(self):
        startrandomloop = random.uniform(0, self.maxdur)
        self.audio.looprec.start = startrandomloop
        self.changeloopstart.SetValue(startrandomloop)
        print 'Random Start'

    # Choix Input du looper
    def changeInputLoop(self, evt):
        if evt.GetInt() == 0:
            print "Input 1"
            self.audio.inputsc.voice = 0.
        elif evt.GetInt() == 1:
            self.audio.inputsc.voice = 1.
            print "Input 2"
        elif evt.GetInt() == 2:
            self.audio.inputsc.voice = 2.
            print "Input 3"
        elif evt.GetInt() == 3:
            self.audio.inputsc.voice = 3.
            print "Input 4"

    # Part l'enregistrement (bouton RECORD LOOP)
    def recordLoop(self, evt):
        if self.recordloop.GetValue() == True:
            self.oscIpad.send([1], '/looprec')
#        if evt.GetInt() == 1:
            self.audio.trigg.play()
            self.audio.looprec.play()
            self.start = time.time()
            print 'Recording Loop'

    # La duree du loop s'adapte (sur un maximum de 8 secondes, la longueur de la table) !
        elif self.recordloop.GetValue() == False:
            self.oscIpad.send([0], '/looprec')
#        elif evt.GetInt() == 0:
            self.end = time.time()
            self.elapsed = self.end - self.start
            self.audio.looprec.dur = self.elapsed
            self.maxdur = self.elapsed
            self.changeloopdur.maxvalue = self.maxdur
            self.changeloopstart.maxvalue = self.maxdur
            self.changeloopdur.SetValue(self.maxdur)

            print "Temps pris: ", self.elapsed, "secondes."
            print 'Stop Recording Loop'

    # Permet de reenregistrer par dessus et ce en gardant la longueur de la boucle originale
    def overdubLoop1(self, evt):
        self.audio.trigg.play()
        self.audio.looprec.play()
        print 'Overdubbing'

    # Part l'enregistrement (bouton RECORD LOOP)
    def reverseLoop(self, evt):
        if self.reverseloop.GetValue() == True:
            self.oscIpad.send([1], '/loopreverse')
            self.audio.looprec.mode = 2
            print 'Forward'
        elif self.reverseloop.GetValue() == False:
            self.oscIpad.send([0], '/loopreverse')
            self.audio.looprec.mode = 1
            print 'Backward'

    def eraseLoop1(self, evt):
        self.audio.tab.reset()

    # Part le loop tout de suite apres l'enregistrement / loop sur la duree enregistree et non sur la longueur du buffer
    def timeLoop(self):
        self.changeloopdur = self.elapsed

    # Mute Loop 1 Right Now
    def killLoop1(self, evt):
        self.audio.looprec.stop()
        print 'Mute Loop 1'

    # Mute Loop 1 After play
    def killafterplayLoop1(self, evt):
        self.audio.looprec.mode = 0
        print 'Mute after Play Loop 1'

    # Play loop if Muted
    def playLoop1(self, evt):
        self.audio.looprec.mode = 1
        self.audio.looprec.play()
        print 'Play Loop 1'

    # Duration Recording Loop
    def changeLoopDur(self, value):
        x = value
        self.audio.looprec.dur = x
        self.oscIpad.send([x], '/loopend')
    # Pitch Recording Loop
    def changeLoopPitch(self, value):
        x = value
        self.audio.looprec.pitch = x
        self.oscIpad.send([x], '/looppitch')

    def changeLoopStart(self, value):
        x = value
        self.audio.looprec.start = x
        self.oscIpad.send([x], '/loopstart')

# Fenetre du Bit Reducer
BitReducerF = BitReducerFrame(None, title='Bit Reducer', pos=(585,50), size=(350,800), process=bitreduce)

# Fenetre du Reverb
ReverbF = ReverbFrame(None, title='Reverb', pos=(230,50), size=(350,800), process=reverb)

# Fenetre du Mixeur
MixeurF = MixeurFrame(None, title='Mixeur', pos=(1195,50), size=(240, 800), process=mixeur)

# Fenetre du boucleur
LoopingF = LoopingFrame(None, title='Loop', pos=(940,50), size=(250, 800), process=audio)

# Ouvre Matrice a l'ouverture de programme
mainFrame = MyFrame(switcher=audio)
t = oscRec()
#mainFrame = MyFrame(None, title="Matrice", pos=(0,50), size=(225,800), switcher=audio)
mainFrame.Show()
app.MainLoop()